
(load-relative "loadtest.rktl")

(Section 'rx)

;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(define (test-regexp result pattern input)
  (test result regexp-match pattern input)
  (test result regexp-match (bytes-append #"(?:" pattern #")") input)
  (test result regexp-match (bytes-append #"(?:(?:" pattern #"))") input)
  (test (and result (cons (car result) result)) 
	regexp-match (bytes-append #"(?:(" pattern #"))") input)
  (test result regexp-match (bytes-append #"(?:)" pattern #"") input)
  (test result regexp-match (bytes-append #"(?<=)" pattern #"") input)
  (test result regexp-match (bytes-append #"(?:^|(?<=.))" pattern #"") input)
  (test result regexp-match (bytes-append #"" pattern #"(?=)") input)
  (test result regexp-match (bytes-append #"" pattern #"(?:$|(?=.))") input)
  (test (and result (cons (car result) result))
	regexp-match (byte-pregexp (bytes-append #"(?=(" pattern #"))\\1")) input)
  (test result regexp-match (bytes-append #"(?>" pattern #")") input)
  )

;; For when adding "x"s to the beginning and end shouldn't change the result:
(define (test-regexp-x result pattern input)
  (test-regexp result pattern input)
  (test-regexp result pattern (bytes-append #"xxx" input #"xxx"))
  )

(test-regexp-x '(#"a") #"a" #"abc")
(test-regexp '(#"a") #"^a" #"abc")
(test-regexp-x '(#"b") #"b" #"abc")
(test-regexp-x #f #"b$" #"abc")
(test-regexp-x '(#"c") #"c" #"abc")
(test-regexp-x #f #"^c" #"abc")
(test-regexp '(#"c") #"c$" #"abc")

(test-regexp '(#"a") #"." #"abc")
(test-regexp '(#"a") #"^." #"abc")
(test-regexp-x '(#"a") #"[a-b]" #"abc")
(test-regexp '(#"b") #"[^a]" #"abc")
(test-regexp '(#"c") #"[^ab]" #"abc")
(test-regexp '(#"c") #"[^a-b]" #"abc")
(test-regexp '(#"c") #".$" #"abc")

(test-regexp '(#"a") #".?" #"abc")
(test-regexp '(#"a") #"a?" #"abc")
(test-regexp '(#"a") #"a*" #"abc")
(test-regexp '(#"a" #"a") #"(a)?" #"abc")
(test-regexp '(#"a" #"a") #"(a)*" #"abc")
(test-regexp-x '(#"") #"b?" #"abc")
(test-regexp-x '(#"b") #"b+" #"abc")
(test-regexp-x '(#"b") #"b+?" #"abc")
(test-regexp-x '(#"") #"b*" #"abc")
(test-regexp-x '(#"c") #"c+" #"abc")
(test-regexp-x '(#"c") #"c+?" #"abc")
(test-regexp-x '(#"") #"c*" #"abc")

(test-regexp-x '(#"ab") #"ab" #"abc")
(test-regexp-x '(#"ab" #"a" #"b") #"(a)(b)" #"abc")
(test-regexp '(#"ab" #"a" #"b") #"(a)*(b)*" #"abc")
(test-regexp-x '(#"bc") #"bc" #"abc")
(test-regexp '(#"ab") #".." #"abc")
(test-regexp-x '(#"abc") #".bc" #"abc")
(test-regexp '(#"abc") #"..*" #"abc")
(test-regexp '(#"abc") #"[a-c]*" #"abc")
(test-regexp-x '(#"abc") #"[a-c]+" #"abc")

(test-regexp '(#"abc") #".*" #"abc")
(test-regexp-x '(#"") #".*?" #"abc")
(test-regexp '(#"abc") #".*?c" #"abc")
(test-regexp '(#"abc") #".+" #"abc")
(test-regexp '(#"a") #".+?" #"abc")
(test-regexp '(#"abc") #".+?c" #"abc")

(test-regexp-x '(#"abc") #"(?:a|b)*c" #"abc")
(test-regexp '(#"abc") #"(?:a|b|c)*" #"abc")
(test-regexp '(#"abc") #"(?:a|(?:b|c))*" #"abc")
(test-regexp '(#"") #"(?:b|c)*" #"abc")

(test-regexp-x '(#"abc") #"(?:a|b)+c" #"abc")
(test-regexp-x '(#"abc") #"(?:a|b|c)+" #"abc")
(test-regexp-x '(#"abc") #"(?:a|(?:b|c))+" #"abc")
(test-regexp-x '(#"bc") #"(?:b|c)+" #"abc")

(test-regexp-x '(#"abc" #"b") #"(a|b)*c" #"abc")
(test-regexp '(#"abc" #"c") #"(a|b|c)*" #"abc")
(test-regexp '(#"abc" #"c" #"c") #"(a|(b|c))*" #"abc")
(test-regexp '(#"abc" #"c" #"b") #"((a|b)|c)*" #"abc")
(test-regexp '(#"" #f) #"(b|c)*" #"abc")

(test-regexp-x '(#"abc" #"b") #"(a|b)+c" #"abc")
(test-regexp-x '(#"abc" #"c") #"(a|b|c)+" #"abc")
(test-regexp-x '(#"abc" #"c" #"c") #"(a|(b|c))+" #"abc")
(test-regexp-x '(#"abc" #"c" #"b") #"((a|b)|c)+" #"abc")

;; Make sure we hit all types of ranges, with and without regstart:
;; EXACT1:
(test-regexp-x '(#"a") #"a" #"a")
(test-regexp-x #f #"a" #"b")
(test-regexp '(#"aaa") #"a*" #"aaa")
(test-regexp-x '(#"") #"a*" #"bbb")
(test-regexp-x '(#"a") #"q?a" #"a")
(test-regexp-x #f #"q?a" #"b")
;; RANGE:
(test-regexp-x '(#"a") #"[a-b]" #"a")
(test-regexp-x '(#"b") #"[a-b]" #"b")
(test-regexp-x #f #"[a-b]" #"c")
(test-regexp '(#"aba") #"[a-b]*" #"abac")
(test-regexp-x '(#"") #"[a-b]*" #"cbbb")
(test-regexp-x '(#"a") #"q?[a-b]" #"a")
(test-regexp-x '(#"b") #"q?[a-b]" #"b")
(test-regexp-x #f #"q?[a-b]" #"c")
;; NOTRANGE:
(test-regexp '(#"a") #"[^c-d]" #"a")
(test-regexp '(#"b") #"[^c-d]" #"b")
(test-regexp #f #"[^c-d]" #"c")
(test-regexp '(#"aba") #"[^c-d]*" #"abac")
(test-regexp '(#"") #"[^c-d]*" #"cbbb")
(test-regexp '(#"a") #"q?[^c-d]" #"a")
(test-regexp '(#"b") #"q?[^c-d]" #"b")
(test-regexp #f #"q?[^c-d]" #"c")
;; ANYOF:
(test-regexp '(#"a") #"[ad]" #"a")
(test-regexp '(#"d") #"[ad]" #"d")
(test-regexp #f #"[ad]" #"c")
(test-regexp '(#"ada") #"[ad]*" #"adac")
(test-regexp '(#"") #"[ad]*" #"cddd")
(test-regexp '(#"a") #"q?[ad]" #"a")
(test-regexp '(#"d") #"q?[ad]" #"d")
(test-regexp #f #"q?[ad]" #"c")

(test '(#"a") regexp-match #rx#"^[^\0]" #"aaa\0")
(test #f regexp-match #rx#"^[^\0]" #"\0aaa\0")
(test '(#"aaa") regexp-match #rx#"^[^\0]*" #"aaa\0")

(map (lambda (t)
       (err/rt-test (byte-pregexp t))
       (err/rt-test (pregexp t)))
     '(#")"
       #"*"
       #"?"
       #"+"))

(map (lambda (as-string?)
       (map (lambda (p)
              (let ([name (car p)]
                    [predicate (cdr p)]
                    [mk (lambda (name extra not? star?)
                          ((if as-string? pregexp byte-pregexp)
                           ((if as-string? values string->bytes/latin-1)
                            (format "[~a~a[:~a:]]~a" 
                                    (if not? "^" "")
                                    (if extra extra "")
                                    name
                                    (if star? "*" "")))))]
                    [-bytes (if as-string?
                                (lambda l
                                  (bytes->string/latin-1 (apply bytes l)))
                                bytes)])
                (let ([try
                       (lambda (extra)
                         (let ([b (mk name extra #f #f)]
                               [not-b (mk name extra #t #f)]
                               [b* (mk name extra #f #t)]
                               [not-b* (mk name extra #t #t)])
                           (let loop ([c 0])
                             (unless (= c 128)
                               (let ([in? (or (and extra
                                                   (= c (char->integer extra)))
                                              (predicate (integer->char c)))])
                                 (test (if in? (list (-bytes c)) #f)
                                       regexp-match 
                                       b
                                       (-bytes c))
                                 (test (if in? (list (-bytes c c)) (list (-bytes)))
                                       regexp-match 
                                       b*
                                       (-bytes c c))
                                 (test (if in? #f (list (-bytes c)))
                                       regexp-match 
                                       not-b
                                       (-bytes c))
                                 (test (if in? (list (-bytes)) (list (-bytes c c)))
                                       regexp-match 
                                       not-b*
                                       (-bytes c c))
                                 (loop (add1 c)))))
                           (test #f regexp-match b (-bytes 128))
                           (test (list (-bytes)) regexp-match b* (-bytes 128 128))
                           (test (list (-bytes 128)) regexp-match not-b (-bytes 128))
                           (test (list (-bytes 128 128)) regexp-match not-b* (-bytes 128 128))))])
                  (try #f)
                  (try #\377)
                  (unless (predicate #\x)
                    (try #\x))
                  (unless (predicate #\space)
                    (try #\space))
                  (unless (predicate #\000)
                    (try #\000))
                  (unless (predicate #\002)
                    (try #\002)))))
            (list
             (cons "alpha" char-alphabetic?)
             (cons "alnum" (lambda (x)
                             (or (char-alphabetic? x)
                                 (char-numeric? x))))
             )))
     '(#f #t))

(test '("app\u039Be") regexp-match #px"(?i:app\u039Be)" "app\u039Be")
(test '("app\u039Be") regexp-match #px"(?i:app\u03BBe)" "app\u039Be")
(test #f regexp-match #px"app\u03BBe" "app\u039Be")
(test #f regexp-match #px"(?i:(?-i:app\u03BBe))" "app\u039Be")
(test '("app\u039Be") regexp-match #px"(?i:(?-i:app)\u03BBe)" "app\u039Be")
(test '("app\u03BBe") regexp-match #px"(?i:app\u039Be)" "app\u03BBe")
(test '("app\u03BBe") regexp-match #px"(?i:app[\u039B-\u039C]e)" "app\u03BBe")
(test '("app\u039Be") regexp-match #px"(?i:app[\u03BB-\u03BC]e)" "app\u039Be")

(let ([sigmas '(#\u03A3 #\u03C2 #\u03C3)]
      [lambdas '(#\u039B #\u039B #\u03BB)])
  (for-each (lambda (s1)
	      (for-each
	       (lambda (s2 l2)
		 (let* ([r (list (format "_~a_" s1))]
			[gen-sigma? (or (equal? s2 #\u03C2)
					(not (equal? s1 #\u03C2)))]
			[gr (and gen-sigma? r)])
		   (if (equal? s1 s2)
		       (test r regexp-match (format "_~a_" s2) (format "_~a_" s1))
		       (test #f regexp-match (format "_~a_" s2) (format "_~a_" s1)))
		   (test gr regexp-match (format "(?i:_~a_)" s2) (format "_~a_" s1))
		   (test gr regexp-match (format "(?i:_[~a]_)" s2) (format "_~a_" s1))
		   (test (and (not (equal? s1 s2)) r) regexp-match (format "_[^~a]_" s2) (format "_~a_" s1))
		   (test (and (equal? s1 #\u03C2) (not (equal? s2 #\u03C2)) r)
			 regexp-match (format "(?i:_[^~a]_)" s2) (format "_~a_" s1))
		   (test gr regexp-match (format "(?i:_[x~a]_)" s2) (format "_~a_" s1))
		   (test gr regexp-match (format "(?i:_[~a\x1888]_)" s2) (format "_~a_" s1))
		   (test gr regexp-match (format "(?i:_[~a-~a]_)" s2 s2) (format "_~a_" s1))
		   (test r regexp-match (format "_[~a-~a]_" (car sigmas) (caddr sigmas)) (format "_~a_" s1))
		   (test (and (char<=? (car sigmas) s1 s2) r)
			 regexp-match (format "_[~a-~a]_" (car sigmas) s2) (format "_~a_" s1))
		   (test (and (char<=? s2 s1 (caddr sigmas)) r)
			 regexp-match (format "_[~a-~a]_" s2 (caddr sigmas)) (format "_~a_" s1))
		   (test (and (or gen-sigma? (equal? s2 #\u03C3)) r)
			 regexp-match (format "(?i:_[~a-~a]_)" (car sigmas) s2) (format "_~a_" s1))
		   (test (and (or gen-sigma? (equal? s2 #\u03A3)) r)
			 regexp-match (format "(?i:_[~a-~a]_)" s2 (caddr sigmas)) (format "_~a_" s1))
		   (test (and (or gen-sigma? (equal? s2 #\u03C3)) r)
			 regexp-match (format "(?i:_[~a-~a]_)" l2 s2) (format "_~a_" s1))))
	       sigmas lambdas))
	    sigmas))

;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Most of the following tests are derived from "testinput" in 
;; CL-PPCRE, which probably is from Perl originally. 
;; The tests have been modified to avoid various incompatibilities.

(define (make-reluctant-port bstr)
  ;; Handing out a single character at a time stresses
  ;; the regexp matcher's lazy reading of a port:
  (define pos 0)
  (define len (bytes-length bstr))
  (make-input-port
   'reluctant-bytes
   (lambda (s)
     (if (pos . >= . len)
         eof
         (begin
           (bytes-set! s 0 (bytes-ref bstr pos))
           (set! pos (add1 pos))
           1)))
   (lambda (s skip evt)
     (if ((+ pos skip) . >= . len)
         eof
         (begin
           (bytes-set! s 0 (bytes-ref bstr (+ pos skip)))
           1)))
   void))

(map (lambda (t)
       (if (pair? t)
	   (begin
	     (test (caddr t) regexp-match (byte-pregexp (car t)) (cadr t))
	     (test (caddr t) regexp-match (byte-pregexp (car t)) (bytes-append #"xxxxxxxxxx" (cadr t)) 10)
	     (test (caddr t) regexp-match (byte-pregexp (car t)) (bytes-append (cadr t) #"xxxxxxxxxx") 0 (bytes-length (cadr t)))
	     (test (caddr t) regexp-match (byte-pregexp (car t)) (open-input-bytes (cadr t)))
	     (test (caddr t) regexp-match (byte-pregexp (car t)) (make-reluctant-port (cadr t)))
	     (test (and (caddr t)
			(map (lambda (v)
			       (and v (bytes->string/latin-1 v)))
			     (caddr t)))
		   regexp-match 
		   (pregexp (bytes->string/latin-1 (car t)))
		   (bytes->string/latin-1 (cadr t)))
	     (test (and (caddr t)
			(map (lambda (v)
			       (and v (string->bytes/utf-8 (bytes->string/latin-1 v))))
			     (caddr t)))
		   regexp-match 
		   (pregexp (bytes->string/latin-1 (car t)))
		   (open-input-string (bytes->string/latin-1 (cadr t)))))
	   (begin
	     (err/rt-test (byte-pregexp t))
	     (err/rt-test (pregexp (bytes->string/latin-1 t))))))
     '(#"}"
       #"]"
       #"[a[:alph:]b]"
       (#"the quick brown fox" #"the quick brown fox" (#"the quick brown fox"))
       (#"the quick brown fox" #"The quick brown FOX" #f)
       (#"the quick brown fox" #"What do you know about the quick brown fox?" (#"the quick brown fox"))
       (#"the quick brown fox" #"What do you know about THE QUICK BROWN FOX?" #f)
       (#"(?i:The quick brown fox)" #"the quick brown fox" (#"the quick brown fox"))
       (#"(?i:The quick brown fox)" #"The quick brown FOX" (#"The quick brown FOX"))
       (#"(?i:The quick brown fox)" #"What do you know about the quick brown fox?" (#"the quick brown fox"))
       (#"(?i:The quick brown fox)" #"What do you know about THE QUICK BROWN FOX?" (#"THE QUICK BROWN FOX"))
       (#"abcd\t\n\r\f\a\e\071\x3b\\$\\\\\\?caxyz" #"abcd\t\n\r\f\a\e9;$\\?caxyz" (#"abcd\t\n\r\f\a\e9;$\\?caxyz"))
       (#"a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz" #"abxyzpqrrrabbxyyyypqAzz" (#"abxyzpqrrrabbxyyyypqAzz"))
       (#"a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz" #"abxyzpqrrrabbxyyyypqAzz" (#"abxyzpqrrrabbxyyyypqAzz"))
       (#"a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz" #"aabxyzpqrrrabbxyyyypqAzz" (#"aabxyzpqrrrabbxyyyypqAzz"))
       (#"a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz" #"aaabxyzpqrrrabbxyyyypqAzz" (#"aaabxyzpqrrrabbxyyyypqAzz"))
       (#"a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz" #"aaaabxyzpqrrrabbxyyyypqAzz" (#"aaaabxyzpqrrrabbxyyyypqAzz"))
       (#"a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz" #"abcxyzpqrrrabbxyyyypqAzz" (#"abcxyzpqrrrabbxyyyypqAzz"))
       (#"a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz" #"aabcxyzpqrrrabbxyyyypqAzz" (#"aabcxyzpqrrrabbxyyyypqAzz"))
       (#"a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz" #"aaabcxyzpqrrrabbxyyyypAzz" (#"aaabcxyzpqrrrabbxyyyypAzz"))
       (#"a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz" #"aaabcxyzpqrrrabbxyyyypqAzz" (#"aaabcxyzpqrrrabbxyyyypqAzz"))
       (#"a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz" #"aaabcxyzpqrrrabbxyyyypqqAzz" (#"aaabcxyzpqrrrabbxyyyypqqAzz"))
       (#"a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz" #"aaabcxyzpqrrrabbxyyyypqqqAzz" (#"aaabcxyzpqrrrabbxyyyypqqqAzz"))
       (#"a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz" #"aaabcxyzpqrrrabbxyyyypqqqqAzz" (#"aaabcxyzpqrrrabbxyyyypqqqqAzz"))
       (#"a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz" #"aaabcxyzpqrrrabbxyyyypqqqqqAzz" (#"aaabcxyzpqrrrabbxyyyypqqqqqAzz"))
       (#"a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz" #"aaabcxyzpqrrrabbxyyyypqqqqqqAzz" (#"aaabcxyzpqrrrabbxyyyypqqqqqqAzz"))
       (#"a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz" #"aaaabcxyzpqrrrabbxyyyypqAzz" (#"aaaabcxyzpqrrrabbxyyyypqAzz"))
       (#"a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz" #"abxyzzpqrrrabbxyyyypqAzz" (#"abxyzzpqrrrabbxyyyypqAzz"))
       (#"a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz" #"aabxyzzzpqrrrabbxyyyypqAzz" (#"aabxyzzzpqrrrabbxyyyypqAzz"))
       (#"a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz" #"aaabxyzzzzpqrrrabbxyyyypqAzz" (#"aaabxyzzzzpqrrrabbxyyyypqAzz"))
       (#"a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz" #"aaaabxyzzzzpqrrrabbxyyyypqAzz" (#"aaaabxyzzzzpqrrrabbxyyyypqAzz"))
       (#"a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz" #"abcxyzzpqrrrabbxyyyypqAzz" (#"abcxyzzpqrrrabbxyyyypqAzz"))
       (#"a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz" #"aabcxyzzzpqrrrabbxyyyypqAzz" (#"aabcxyzzzpqrrrabbxyyyypqAzz"))
       (#"a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz" #"aaabcxyzzzzpqrrrabbxyyyypqAzz" (#"aaabcxyzzzzpqrrrabbxyyyypqAzz"))
       (#"a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz" #"aaaabcxyzzzzpqrrrabbxyyyypqAzz" (#"aaaabcxyzzzzpqrrrabbxyyyypqAzz"))
       (#"a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz" #"aaaabcxyzzzzpqrrrabbbxyyyypqAzz" (#"aaaabcxyzzzzpqrrrabbbxyyyypqAzz"))
       (#"a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz" #"aaaabcxyzzzzpqrrrabbbxyyyyypqAzz" (#"aaaabcxyzzzzpqrrrabbbxyyyyypqAzz"))
       (#"a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz" #"aaabcxyzpqrrrabbxyyyypABzz" (#"aaabcxyzpqrrrabbxyyyypABzz"))
       (#"a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz" #"aaabcxyzpqrrrabbxyyyypABBzz" (#"aaabcxyzpqrrrabbxyyyypABBzz"))
       (#"a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz" #">>>aaabxyzpqrrrabbxyyyypqAzz" (#"aaabxyzpqrrrabbxyyyypqAzz"))
       (#"a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz" #">aaaabxyzpqrrrabbxyyyypqAzz" (#"aaaabxyzpqrrrabbxyyyypqAzz"))
       (#"a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz" #">>>>abcxyzpqrrrabbxyyyypqAzz" (#"abcxyzpqrrrabbxyyyypqAzz"))
       (#"a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz" #"abxyzpqrrabbxyyyypqAzz" #f)
       (#"a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz" #"abxyzpqrrrrabbxyyyypqAzz" #f)
       (#"a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz" #"abxyzpqrrrabxyyyypqAzz" #f)
       (#"a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz" #"aaaabcxyzzzzpqrrrabbbxyyyyyypqAzz" #f)
       (#"a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz" #"aaaabcxyzzzzpqrrrabbbxyyypqAzz" #f)
       (#"a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz" #"aaabcxyzpqrrrabbxyyyypqqqqqqqAzz" #f)
       (#"^(abc){1,2}zz" #"abczz" (#"abczz" #"abc"))
       (#"^(abc){1,2}zz" #"abcabczz" (#"abcabczz" #"abc"))
       (#"^(abc){1,2}zz" #"zz" #f)
       (#"^(abc){1,2}zz" #"abcabcabczz" #f)
       (#"^(abc){1,2}zz" #">>abczz" #f)
       (#"^(b+?|a){1,2}?c" #"bc" (#"bc" #"b"))
       (#"^(b+?|a){1,2}?c" #"bbc" (#"bbc" #"b"))
       (#"^(b+?|a){1,2}?c" #"bbbc" (#"bbbc" #"bb"))
       (#"^(b+?|a){1,2}?c" #"bac" (#"bac" #"a"))
       (#"^(b+?|a){1,2}?c" #"bbac" (#"bbac" #"a"))
       (#"^(b+?|a){1,2}?c" #"aac" (#"aac" #"a"))
       (#"^(b+?|a){1,2}?c" #"abbbbbbbbbbbc" (#"abbbbbbbbbbbc" #"bbbbbbbbbbb"))
       (#"^(b+?|a){1,2}?c" #"bbbbbbbbbbbac" (#"bbbbbbbbbbbac" #"a"))
       (#"^(b+?|a){1,2}?c" #"aaac" #f)
       (#"^(b+?|a){1,2}?c" #"abbbbbbbbbbbac" #f)
       (#"^(b+|a){1,2}c" #"bc" (#"bc" #"b"))
       (#"^(b+|a){1,2}c" #"bbc" (#"bbc" #"bb"))
       (#"^(b+|a){1,2}c" #"bbbc" (#"bbbc" #"bbb"))
       (#"^(b+|a){1,2}c" #"bac" (#"bac" #"a"))
       (#"^(b+|a){1,2}c" #"bbac" (#"bbac" #"a"))
       (#"^(b+|a){1,2}c" #"aac" (#"aac" #"a"))
       (#"^(b+|a){1,2}c" #"abbbbbbbbbbbc" (#"abbbbbbbbbbbc" #"bbbbbbbbbbb"))
       (#"^(b+|a){1,2}c" #"bbbbbbbbbbbac" (#"bbbbbbbbbbbac" #"a"))
       (#"^(b+|a){1,2}c" #"aaac" #f)
       (#"^(b+|a){1,2}c" #"abbbbbbbbbbbac" #f)
       (#"^(b+|a){1,2}?bc" #"bbc" (#"bbc" #"b"))
       #"^(b*|ba){1,2}?bc"
       (#"(.)c|ad" #"ad" (#"ad" #f))
       (#"(a)c|ad" #"ad" (#"ad" #f))
       (#"(?<=(a))c|d" #"ad" (#"d" #f))
       (#"(?=(a))ac|ad" #"ad" (#"ad" #f))
       (#"^[ab\\]cde]" #"athing" (#"a"))
       (#"^[ab\\]cde]" #"bthing" (#"b"))
       (#"^[ab\\]cde]" #"]thing" (#"]"))
       (#"^[ab\\]cde]" #"cthing" (#"c"))
       (#"^[ab\\]cde]" #"dthing" (#"d"))
       (#"^[ab\\]cde]" #"ething" (#"e"))
       (#"^[ab\\]cde]" #"fthing" #f)
       (#"^[ab\\]cde]" #"[thing" #f)
       (#"^[ab\\]cde]" #"\\\\thing" #f)
       (#"^[]cde]" #"]thing" (#"]"))
       (#"^[]cde]" #"cthing" (#"c"))
       (#"^[]cde]" #"dthing" (#"d"))
       (#"^[]cde]" #"ething" (#"e"))
       (#"^[]cde]" #"athing" #f)
       (#"^[]cde]" #"fthing" #f)
       (#"^[^ab\\]cde]" #"fthing" (#"f"))
       (#"^[^ab\\]cde]" #"[thing" (#"["))
       (#"^[^ab\\]cde]" #"\\\\thing" (#"\\"))
       (#"^[^ab\\]cde]" #"athing" #f)
       (#"^[^ab\\]cde]" #"bthing" #f)
       (#"^[^ab\\]cde]" #"]thing" #f)
       (#"^[^ab\\]cde]" #"cthing" #f)
       (#"^[^ab\\]cde]" #"dthing" #f)
       (#"^[^ab\\]cde]" #"ething" #f)
       (#"^[^]cde]" #"athing" (#"a"))
       (#"^[^]cde]" #"fthing" (#"f"))
       (#"^[^]cde]" #"]thing" #f)
       (#"^[^]cde]" #"cthing" #f)
       (#"^[^]cde]" #"dthing" #f)
       (#"^[^]cde]" #"ething" #f)
       (#"^\\\201" #"\201" (#"\201"))
       (#"^\377" #"\377" (#"\377"))
       (#"^[0-9]+$" #"0" (#"0"))
       (#"^[0-9]+$" #"1" (#"1"))
       (#"^[0-9]+$" #"2" (#"2"))
       (#"^[0-9]+$" #"3" (#"3"))
       (#"^[0-9]+$" #"4" (#"4"))
       (#"^[0-9]+$" #"5" (#"5"))
       (#"^[0-9]+$" #"6" (#"6"))
       (#"^[0-9]+$" #"7" (#"7"))
       (#"^[0-9]+$" #"8" (#"8"))
       (#"^[0-9]+$" #"9" (#"9"))
       (#"^[0-9]+$" #"10" (#"10"))
       (#"^[0-9]+$" #"100" (#"100"))
       (#"^[0-9]+$" #"abc" #f)
       (#"^.*nter" #"enter" (#"enter"))
       (#"^.*nter" #"inter" (#"inter"))
       (#"^.*nter" #"uponter" (#"uponter"))
       (#"^xxx[0-9]+$" #"xxx0" (#"xxx0"))
       (#"^xxx[0-9]+$" #"xxx1234" (#"xxx1234"))
       (#"^xxx[0-9]+$" #"xxx" #f)
       (#"^.+[0-9][0-9][0-9]$" #"x123" (#"x123"))
       (#"^.+[0-9][0-9][0-9]$" #"xx123" (#"xx123"))
       (#"^.+[0-9][0-9][0-9]$" #"123456" (#"123456"))
       (#"^.+[0-9][0-9][0-9]$" #"123" #f)
       (#"^.+[0-9][0-9][0-9]$" #"x1234" (#"x1234"))
       (#"^.+?[0-9][0-9][0-9]$" #"x123" (#"x123"))
       (#"^.+?[0-9][0-9][0-9]$" #"xx123" (#"xx123"))
       (#"^.+?[0-9][0-9][0-9]$" #"123456" (#"123456"))
       (#"^.+?[0-9][0-9][0-9]$" #"123" #f)
       (#"^.+?[0-9][0-9][0-9]$" #"x1234" (#"x1234"))
       (#"^([^!]+)!(.+)=apquxz\\.ixr\\.zzz\\.ac\\.uk$" #"abc!pqr=apquxz.ixr.zzz.ac.uk" (#"abc!pqr=apquxz.ixr.zzz.ac.uk" #"abc" #"pqr"))
       (#"^([^!]+)!(.+)=apquxz\\.ixr\\.zzz\\.ac\\.uk$" #"!pqr=apquxz.ixr.zzz.ac.uk" #f)
       (#"^([^!]+)!(.+)=apquxz\\.ixr\\.zzz\\.ac\\.uk$" #"abc!=apquxz.ixr.zzz.ac.uk" #f)
       (#"^([^!]+)!(.+)=apquxz\\.ixr\\.zzz\\.ac\\.uk$" #"abc!pqr=apquxz:ixr.zzz.ac.uk" #f)
       (#"^([^!]+)!(.+)=apquxz\\.ixr\\.zzz\\.ac\\.uk$" #"abc!pqr=apquxz.ixr.zzz.ac.ukk" #f)
       (#":" #"Well, we need a colon: somewhere" (#":"))
       (#":" #"Fail if we don't" #f)
       (#"(?i:([\\da-f:]+)$)" #"0abc" (#"0abc" #"0abc"))
       (#"(?i:([\\da-f:]+)$)" #"abc" (#"abc" #"abc"))
       (#"(?i:([\\da-f:]+)$)" #"fed" (#"fed" #"fed"))
       (#"(?i:([\\da-f:]+)$)" #"E" (#"E" #"E"))
       (#"(?i:([\\da-f:]+)$)" #"::" (#"::" #"::"))
       (#"(?i:([\\da-f:]+)$)" #"5f03:12C0::932e" (#"5f03:12C0::932e" #"5f03:12C0::932e"))
       (#"(?i:([\\da-f:]+)$)" #"fed def" (#"def" #"def"))
       (#"(?i:([\\da-f:]+)$)" #"Any old stuff" (#"ff" #"ff"))
       (#"(?i:([\\da-f:]+)$)" #"0zzz" #f)
       (#"(?i:([\\da-f:]+)$)" #"gzzz" #f)
       (#"(?i:([\\da-f:]+)$)" #"fed\\x20" (#"20" #"20"))
       (#"(?i:([\\da-f:]+)$)" #"Any old rubbish" #f)
       (#"^.*\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})$" #".1.2.3" (#".1.2.3" #"1" #"2" #"3"))
       (#"^.*\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})$" #"A.12.123.0" (#"A.12.123.0" #"12" #"123" #"0"))
       (#"^.*\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})$" #".1.2.3333" #f)
       (#"^.*\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})$" #"1.2.3" #f)
       (#"^.*\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})$" #"1234.2.3" #f)
       (#"^(\\d+)\\s+IN\\s+SOA\\s+(\\S+)\\s+(\\S+)\\s*\\(\\s*$" #"1 IN SOA non-sp1 non-sp2(" (#"1 IN SOA non-sp1 non-sp2(" #"1" #"non-sp1" #"non-sp2"))
       (#"^(\\d+)\\s+IN\\s+SOA\\s+(\\S+)\\s+(\\S+)\\s*\\(\\s*$" #"1    IN    SOA    non-sp1    non-sp2   (" (#"1    IN    SOA    non-sp1    non-sp2   (" #"1" #"non-sp1" #"non-sp2"))
       (#"^(\\d+)\\s+IN\\s+SOA\\s+(\\S+)\\s+(\\S+)\\s*\\(\\s*$" #"1IN SOA non-sp1 non-sp2(" #f)
       (#"^[a-zA-Z\\d][a-zA-Z\\d\\-]*(\\.[a-zA-Z\\d][a-zA-Z\\d\\-]*)*\\.$" #"a." (#"a." #f))
       (#"^[a-zA-Z\\d][a-zA-Z\\d\\-]*(\\.[a-zA-Z\\d][a-zA-Z\\d\\-]*)*\\.$" #"Z." (#"Z." #f))
       (#"^[a-zA-Z\\d][a-zA-Z\\d\\-]*(\\.[a-zA-Z\\d][a-zA-Z\\d\\-]*)*\\.$" #"2." (#"2." #f))
       (#"^[a-zA-Z\\d][a-zA-Z\\d\\-]*(\\.[a-zA-Z\\d][a-zA-Z\\d\\-]*)*\\.$" #"ab-c.pq-r." (#"ab-c.pq-r." #".pq-r"))
       (#"^[a-zA-Z\\d][a-zA-Z\\d\\-]*(\\.[a-zA-Z\\d][a-zA-Z\\d\\-]*)*\\.$" #"sxk.zzz.ac.uk." (#"sxk.zzz.ac.uk." #".uk"))
       (#"^[a-zA-Z\\d][a-zA-Z\\d\\-]*(\\.[a-zA-Z\\d][a-zA-Z\\d\\-]*)*\\.$" #"x-.y-." (#"x-.y-." #".y-"))
       (#"^[a-zA-Z\\d][a-zA-Z\\d\\-]*(\\.[a-zA-Z\\d][a-zA-Z\\d\\-]*)*\\.$" #"-abc.peq." #f)
       (#"^\\*\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?(\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?)*$" #"*.a" (#"*.a" #f #f #f))
       (#"^\\*\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?(\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?)*$" #"*.b0-a" (#"*.b0-a" #"0-a" #f #f))
       (#"^\\*\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?(\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?)*$" #"*.c3-b.c" (#"*.c3-b.c" #"3-b" #".c" #f))
       (#"^\\*\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?(\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?)*$" #"*.c-a.b-c" (#"*.c-a.b-c" #"-a" #".b-c" #"-c"))
       (#"^\\*\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?(\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?)*$" #"*.0" #f)
       (#"^\\*\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?(\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?)*$" #"*.a-" #f)
       (#"^\\*\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?(\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?)*$" #"*.a-b.c-" #f)
       (#"^\\*\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?(\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?)*$" #"*.c-a.0-c" #f)
       (#"^(?=ab(de))(abd)(e)" #"abde" (#"abde" #"de" #"abd" #"e"))
       (#"^(?!(ab)de|x)(abd)(f)" #"abdf" (#"abdf" #f #"abd" #"f"))
       (#"^(?=(ab(cd)))(ab)" #"abcd" (#"ab" #"abcd" #"cd" #"ab"))
       (#"(?i:^[\\da-f](\\.[\\da-f])*$)" #"a.b.c.d" (#"a.b.c.d" #".d"))
       (#"(?i:^[\\da-f](\\.[\\da-f])*$)" #"A.B.C.D" (#"A.B.C.D" #".D"))
       (#"(?i:^[\\da-f](\\.[\\da-f])*$)" #"a.b.c.1.2.3.C" (#"a.b.c.1.2.3.C" #".C"))
       (#"^\\\".*\\\"\\s*(;.*)?$" #"\"1234\"" (#"\"1234\"" #f))
       (#"^\\\".*\\\"\\s*(;.*)?$" #"\"abcd\" ;" (#"\"abcd\" ;" #";"))
       (#"^\\\".*\\\"\\s*(;.*)?$" #"\"\" ; rhubarb" (#"\"\" ; rhubarb" #"; rhubarb"))
       (#"^\\\".*\\\"\\s*(;.*)?$" #"\"1234\" : things" #f)
       (#"^$" #"\\" #f)
       (#"^(a(b(c)))(d(e(f)))(h(i(j)))(k(l(m)))$" #"abcdefhijklm" (#"abcdefhijklm" #"abc" #"bc" #"c" #"def" #"ef" #"f" #"hij" #"ij" #"j" #"klm" #"lm" #"m"))
       (#"^(?:a(b(c)))(?:d(e(f)))(?:h(i(j)))(?:k(l(m)))$" #"abcdefhijklm" (#"abcdefhijklm" #"bc" #"c" #"ef" #"f" #"ij" #"j" #"lm" #"m"))
;       (#"^[\\w][\\W][\\s][\\S][\\d][\\D][\\b][\\n][\\c]][\\022]" #"a+ Z0+\\x08\\n\\x1d\\x12" #f)
       (#"^[.^$|()*+?{,}]+" #".^\\$(*+)|{?,?}" (#".^"))
       (#"^a*\\w" #"z" (#"z"))
       (#"^a*\\w" #"az" (#"az"))
       (#"^a*\\w" #"aaaz" (#"aaaz"))
       (#"^a*\\w" #"a" (#"a"))
       (#"^a*\\w" #"aa" (#"aa"))
       (#"^a*\\w" #"aaaa" (#"aaaa"))
       (#"^a*\\w" #"a+" (#"a"))
       (#"^a*\\w" #"aa+" (#"aa"))
       (#"^a*?\\w" #"z" (#"z"))
       (#"^a*?\\w" #"az" (#"a"))
       (#"^a*?\\w" #"aaaz" (#"a"))
       (#"^a*?\\w" #"a" (#"a"))
       (#"^a*?\\w" #"aa" (#"a"))
       (#"^a*?\\w" #"aaaa" (#"a"))
       (#"^a*?\\w" #"a+" (#"a"))
       (#"^a*?\\w" #"aa+" (#"a"))
       (#"^a+\\w" #"az" (#"az"))
       (#"^a+\\w" #"aaaz" (#"aaaz"))
       (#"^a+\\w" #"aa" (#"aa"))
       (#"^a+\\w" #"aaaa" (#"aaaa"))
       (#"^a+\\w" #"aa+" (#"aa"))
       (#"^a+?\\w" #"az" (#"az"))
       (#"^a+?\\w" #"aaaz" (#"aa"))
       (#"^a+?\\w" #"aa" (#"aa"))
       (#"^a+?\\w" #"aaaa" (#"aa"))
       (#"^a+?\\w" #"aa+" (#"aa"))
       (#"^\\d{8}\\w{2,}" #"1234567890" (#"1234567890"))
       (#"^\\d{8}\\w{2,}" #"12345678ab" (#"12345678ab"))
       (#"^\\d{8}\\w{2,}" #"12345678__" (#"12345678__"))
       (#"^\\d{8}\\w{2,}" #"1234567" #f)
       (#"^[aeiou\\d]{4,5}$" #"uoie" (#"uoie"))
       (#"^[aeiou\\d]{4,5}$" #"1234" (#"1234"))
       (#"^[aeiou\\d]{4,5}$" #"12345" (#"12345"))
       (#"^[aeiou\\d]{4,5}$" #"aaaaa" (#"aaaaa"))
       (#"^[aeiou\\d]{4,5}$" #"123456" #f)
       (#"^[aeiou\\d]{4,5}?" #"uoie" (#"uoie"))
       (#"^[aeiou\\d]{4,5}?" #"1234" (#"1234"))
       (#"^[aeiou\\d]{4,5}?" #"12345" (#"1234"))
       (#"^[aeiou\\d]{4,5}?" #"aaaaa" (#"aaaa"))
       (#"^[aeiou\\d]{4,5}?" #"123456" (#"1234"))
       (#"^(a)(b)(c)(d)(e)(f)(g)(h)(i)(j)(k)\\11*(\\3\\4)\\12$" #"abcdefghijkcda2" #f)
       (#"^(a)(b)(c)(d)(e)(f)(g)(h)(i)(j)(k)\\11*(\\3\\4)\\12$" #"abcdefghijkkkkcda2" #f)
       (#"(cat(a(ract|tonic)|erpillar)) \\1()2(3)" #"cataract cataract23" (#"cataract cataract23" #"cataract" #"aract" #"ract" #"" #"3"))
       (#"(cat(a(ract|tonic)|erpillar)) \\1()2(3)" #"catatonic catatonic23" (#"catatonic catatonic23" #"catatonic" #"atonic" #"tonic" #"" #"3"))
       (#"(cat(a(ract|tonic)|erpillar)) \\1()2(3)" #"caterpillar caterpillar23" (#"caterpillar caterpillar23" #"caterpillar" #"erpillar" #f #"" #"3"))
       (#"^From +([^ ]+) +[a-zA-Z][a-zA-Z][a-zA-Z] +[a-zA-Z][a-zA-Z][a-zA-Z] +[0-9]?[0-9] +[0-9][0-9]:[0-9][0-9]" #"From abcd  Mon Sep 01 12:33:02 1997" (#"From abcd  Mon Sep 01 12:33" #"abcd"))
       (#"^From\\s+\\S+\\s+([a-zA-Z]{3}\\s+){2}\\d{1,2}\\s+\\d\\d:\\d\\d" #"From abcd  Mon Sep 01 12:33:02 1997" (#"From abcd  Mon Sep 01 12:33" #"Sep "))
       (#"^From\\s+\\S+\\s+([a-zA-Z]{3}\\s+){2}\\d{1,2}\\s+\\d\\d:\\d\\d" #"From abcd  Mon Sep  1 12:33:02 1997" (#"From abcd  Mon Sep  1 12:33" #"Sep  "))
       (#"^From\\s+\\S+\\s+([a-zA-Z]{3}\\s+){2}\\d{1,2}\\s+\\d\\d:\\d\\d" #"From abcd  Sep 01 12:33:02 1997" #f)
       (#"\\w+(?=\t)" #"the quick brown\\t fox" #f)
       (#"foo(?!bar)(.*)" #"foobar is foolish see?" (#"foolish see?" #"lish see?"))
       (#"(?:(?!foo)...|^.{0,2})bar(.*)" #"foobar crowbar etc" (#"rowbar etc" #" etc"))
       (#"(?:(?!foo)...|^.{0,2})bar(.*)" #"barrel" (#"barrel" #"rel"))
       (#"(?:(?!foo)...|^.{0,2})bar(.*)" #"2barrel" (#"2barrel" #"rel"))
       (#"(?:(?!foo)...|^.{0,2})bar(.*)" #"A barrel" (#"A barrel" #"rel"))
       (#"^(\\D*)(?=\\d)(?!123)" #"abc456" (#"abc" #"abc"))
       (#"^(\\D*)(?=\\d)(?!123)" #"abc123" #f)
       (#"^(a)\\1{2,3}(.)" #"aaab" (#"aaab" #"a" #"b"))
       (#"^(a)\\1{2,3}(.)" #"aaaab" (#"aaaab" #"a" #"b"))
       (#"^(a)\\1{2,3}(.)" #"aaaaab" (#"aaaaa" #"a" #"a"))
       (#"^(a)\\1{2,3}(.)" #"aaaaaab" (#"aaaaa" #"a" #"a"))
       (#"(?!^)abc" #"the abc" (#"abc"))
       (#"(?!^)abc" #"abc" #f)
       (#"(?=^)abc" #"abc" (#"abc"))
       (#"(?=^)abc" #"the abc" #f)
       (#"^[ab]{1,3}(ab*|b)" #"aabbbbb" (#"aabb" #"b"))
       (#"^[ab]{1,3}?(ab*|b)" #"aabbbbb" (#"aabbbbb" #"abbbbb"))
       (#"^[ab]{1,3}?(ab*?|b)" #"aabbbbb" (#"aa" #"a"))
       (#"^[ab]{1,3}(ab*?|b)" #"aabbbbb" (#"aabb" #"b"))
#|
       (#"abc\\0def\\00pqr\\000xyz\\0000AB" #"abc\\0def\\00pqr\\000xyz\\0000AB" #f)
       (#"abc\\0def\\00pqr\\000xyz\\0000AB" #"abc456 abc\\0def\\00pqr\\000xyz\\0000ABCDE" #f)
       (#"abc\\x0def\\x00pqr\\x000xyz\\x0000AB" #"abc\\x0def\\x00pqr\\x000xyz\\x0000AB" #f)
       (#"abc\\x0def\\x00pqr\\x000xyz\\x0000AB" #"abc456 abc\\x0def\\x00pqr\\x000xyz\\x0000ABCDE" #f)
       (#"^[\\000-\\037]" #"\\0A" #f)
       (#"^[\\000-\\037]" #"\\01B" #f)
       (#"^[\\000-\\037]" #"\\037C" #f)
       (#"\\0*" #"\\0\\0\\0\\0" #f)
       (#"A\\x0{2,3}Z" #"The A\\x0\\x0Z" #f)
       (#"A\\x0{2,3}Z" #"An A\\0\\x0\\0Z" #f)
       (#"A\\x0{2,3}Z" #"A\\0Z" #f)
       (#"A\\x0{2,3}Z" #"A\\0\\x0\\0\\x0Z" #f)
|#
       (#"^(cow|)\\1(bell)" #"cowcowbell" (#"cowcowbell" #"cow" #"bell"))
       (#"^(cow|)\\1(bell)" #"bell" (#"bell" #"" #"bell"))
       (#"^(cow|)\\1(bell)" #"cowbell" #f)
#|
       (#"^\\s" #"\\040abc" #f)
       (#"^\\s" #"\\x0cabc" #f)
       (#"^\\s" #"\\nabc" #f)
       (#"^\\s" #"\\rabc" #f)
       (#"^\\s" #"\\tabc" #f)
       (#"^\\s" #"abc" #f)
|#
       (#"^(a|x)\\1*b" #"ab" (#"ab" #"a"))
       (#"^(a|x)\\1*b" #"aaaab" (#"aaaab" #"a"))
       (#"^(a|x)\\1*b" #"acb" #f)
       (#"^(a|x)\\1+b" #"aab" (#"aab" #"a"))
       (#"^(a|x)\\1+b" #"aaaab" (#"aaaab" #"a"))
       (#"^(a|x)\\1+b" #"ab" #f)
       (#"^(a|)\\1?b" #"ab" (#"ab" #"a"))
       (#"^(a|)\\1?b" #"aab" (#"aab" #"a"))
       (#"^(a|)\\1?b" #"b" (#"b" #""))
       (#"^(a|)\\1?b" #"acb" #f)
       #"^(a|)\\1{2}b"
       #"^(a|)\\1{2,3}b"
       (#"(^.|\\1){2}" #"aa" (#"aa" #"a")) ; self backreferences are allowed
       (#"(^.|\\1){2}" #"baa" #f)
       (#"(.\\1)" #"aa" #f)
       (#"ab{1,3}bc" #"abbbbc" (#"abbbbc"))
       (#"ab{1,3}bc" #"abbbc" (#"abbbc"))
       (#"ab{1,3}bc" #"abbc" (#"abbc"))
       (#"ab{1,3}bc" #"abc" #f)
       (#"ab{1,3}bc" #"abbbbbc" #f)
       (#"([^.]*)\\.([^:]*):[T ]+(.*)" #"track1.title:TBlah blah blah" (#"track1.title:TBlah blah blah" #"track1" #"title" #"Blah blah blah"))
       (#"(?i:([^.]*)\\.([^:]*):[T ]+(.*))" #"track1.title:TBlah blah blah" (#"track1.title:TBlah blah blah" #"track1" #"title" #"Blah blah blah"))
       (#"(?i:([^.]*)\\.([^:]*):[t ]+(.*))" #"track1.title:TBlah blah blah" (#"track1.title:TBlah blah blah" #"track1" #"title" #"Blah blah blah"))
       (#"^[W-c]+$" #"WXY_^abc" (#"WXY_^abc"))
       (#"^[W-c]+$" #"wxy" #f)
       (#"(?i:^[W-c]+$)" #"WXY_^abc" (#"WXY_^abc"))
       (#"(?i:^[W-c]+$)" #"wxy_^ABC" (#"wxy_^ABC"))
       (#"(?i:^[\x3f-\x5F]+$)" #"WXY_^abc" (#"WXY_^abc"))
       (#"(?i:^[\x3f-\x5F]+$)" #"wxy_^ABC" (#"wxy_^ABC"))
       (#"(?:b)|(?::+)" #"b::c" (#"b"))
       (#"(?:b)|(?::+)" #"c::b" (#"::"))
       (#"[-az]+" #"az-" (#"az-"))
       (#"[-az]+" #"b" #f)
       (#"[az-]+" #"za-" (#"za-"))
       (#"[az-]+" #"b" #f)
       (#"[a\\-z]+" #"a-z" (#"a-z"))
       (#"[a\\-z]+" #"b" #f)
       (#"[a-z]+" #"abcdxyz" (#"abcdxyz"))
       (#"[\\d-]+" #"12-34" (#"12-34"))
       (#"[\\d-]+" #"aaa" #f)
       #"[\\d-z]"
       (#"[\\dz-]+" #"12-34z" (#"12-34z"))
       (#"[\\dz-]+" #"aaa" #f)
       (#"\\\x5c" #"\\\\" (#"\\"))
       (#"\x20Z" #"the Zoo" (#" Z"))
       (#"\x20Z" #"Zulu" #f)
       (#"(?i:(abc)\\1)" #"abcabc" (#"abcabc" #"abc"))
       (#"(?i:(abc)\\1)" #"ABCabc" (#"ABCabc" #"ABC"))
       (#"(?i:(abc)\\1)" #"abcABC" (#"abcABC" #"abc"))
       (#"ab\\{3cd" #"ab{3cd" (#"ab{3cd"))
       #"ab{3cd"
       (#"ab\\{3,cd" #"ab{3,cd" (#"ab{3,cd"))
       #"ab{3,cd"
       (#"ab\\{3,4a\\}cd" #"ab{3,4a}cd" (#"ab{3,4a}cd"))
       #"ab{3,4a}cd"
       (#"\\{4,5a\\}bc" #"{4,5a}bc" (#"{4,5a}bc"))
       #"{4,5a}bc"
       (#"(abc)\123" #"abc\x53" (#"abcS" #"abc"))
       (#"(abc)\223" #"abc\x93" (#"abc\x93" #"abc"))
       (#"(abc)\323" #"abc\xd3" (#"abc\xd3" #"abc"))
       (#"(a)(b)(c)(d)(e)(f)(g)(h)(i)(j)(k)(l)\\12\123" #"abcdefghijkllS" (#"abcdefghijkllS" #"a" #"b" #"c" #"d" #"e" #"f" #"g" #"h" #"i" #"j" #"k" #"l"))
       #"(a)(b)(c)(d)(e)(f)(g)(h)(i)(j)(k)\\12\123"
       (#"a{0}bc" #"bc" (#"bc"))
       (#"(a|(bc)){0,0}?xyz" #"xyz" (#"xyz" #f #f))
       (#"abc[\\10]de" #"abc\010de" #f)
       (#"abc[\\1]de" #"abc\1de" #f)
       (#"(abc)[\\1]de" #"abc\1de" #f)
       "^([^a])([^\\b])([^c]*)([^d]{3,4})"
       (#"[^a]" #"Abc" (#"A"))
       (#"(?i:[^a])" #"Abc " (#"b"))
       (#"[^a]+" #"AAAaAbc" (#"AAA"))
       (#"(?i:[^a]+)" #"AAAaAbc " (#"bc "))
       (#"[^k]$" #"abc" (#"c"))
       (#"[^k]$" #"abk   " (#" "))
       (#"[^k]{2,3}$" #"abc" (#"abc"))
       (#"[^k]{2,3}$" #"kbc" (#"bc"))
       (#"[^k]{2,3}$" #"kabc " (#"bc "))
       (#"[^k]{2,3}$" #"abk" #f)
       (#"[^k]{2,3}$" #"akb" #f)
       (#"[^k]{2,3}$" #"akk " #f)
       (#"^\\d{8,}\\@.+[^k]$" #"12345678\\@a.b.c.d" #f)
       (#"^\\d{8,}\\@.+[^k]$" #"123456789\\@x.y.z" #f)
       (#"^\\d{8,}\\@.+[^k]$" #"12345678\\@x.y.uk" #f)
       (#"^\\d{8,}\\@.+[^k]$" #"1234567\\@a.b.c.d       " #f)
       (#"(a)\\1{8,}" #"aaaaaaaaa" (#"aaaaaaaaa" #"a"))
       (#"(a)\\1{8,}" #"aaaaaaaaaa" (#"aaaaaaaaaa" #"a"))
       (#"(a)\\1{8,}" #"aaaaaaa   " #f)
       (#"[^a]" #"aaaabcd" (#"b"))
       (#"[^a]" #"aaAabcd " (#"A"))
       (#"(?i:[^a])" #"aaaabcd" (#"b"))
       (#"(?i:[^a])" #"aaAabcd " (#"b"))
       (#"[^az]" #"aaaabcd" (#"b"))
       (#"[^az]" #"aaAabcd " (#"A"))
       (#"(?i:[^az])" #"aaaabcd" (#"b"))
       (#"(?i:[^az])" #"aaAabcd " (#"b"))
       (#"P[^*]TAIRE[^*]{1,6}?LL" #"xxxxxxxxxxxPSTAIREISLLxxxxxxxxx" (#"PSTAIREISLL"))
       (#"P[^*]TAIRE[^*]{1,}?LL" #"xxxxxxxxxxxPSTAIREISLLxxxxxxxxx" (#"PSTAIREISLL"))
       (#"(\\.\\d\\d[1-9]?)\\d+" #"1.230003938" (#".230003938" #".23"))
       (#"(\\.\\d\\d[1-9]?)\\d+" #"1.875000282   " (#".875000282" #".875"))
       (#"(\\.\\d\\d[1-9]?)\\d+" #"1.235  " (#".235" #".23"))
       (#"(\\.\\d\\d((?=0)|\\d(?=\\d)))" #"1.230003938      " (#".23" #".23" #""))
       (#"(\\.\\d\\d((?=0)|\\d(?=\\d)))" #"1.875000282" (#".875" #".875" #"5"))
       (#"(\\.\\d\\d((?=0)|\\d(?=\\d)))" #"1.235 " #f)
       (#"a(?:)b" #"ab " (#"ab"))
       (#"(?i:\\b(foo)\\s+(\\w+))" #"Food is on the foo table" (#"foo table" #"foo" #"table"))
       (#"foo(.*)bar" #"The food is under the bar in the barn." (#"food is under the bar in the bar" #"d is under the bar in the "))
       (#"foo(.*?)bar" #"The food is under the bar in the barn." (#"food is under the bar" #"d is under the "))
       (#"(.*)(\\d*)" #"I have 2 numbers: 53147" (#"I have 2 numbers: 53147" #"I have 2 numbers: 53147" #""))
       (#"(.*)(\\d+)" #"I have 2 numbers: 53147" (#"I have 2 numbers: 53147" #"I have 2 numbers: 5314" #"7"))
       (#"(.*?)(\\d*)" #"I have 2 numbers: 53147" (#"" #"" #""))
       (#"(.*?)(\\d+)" #"I have 2 numbers: 53147" (#"I have 2" #"I have " #"2"))
       (#"(.*)(\\d+)$" #"I have 2 numbers: 53147" (#"I have 2 numbers: 53147" #"I have 2 numbers: 5314" #"7"))
       (#"(.*?)(\\d+)$" #"I have 2 numbers: 53147" (#"I have 2 numbers: 53147" #"I have 2 numbers: " #"53147"))
       (#"(.*)\\b(\\d+)$" #"I have 2 numbers: 53147" (#"I have 2 numbers: 53147" #"I have 2 numbers: " #"53147"))
       (#"(.*\\D)(\\d+)$" #"I have 2 numbers: 53147" (#"I have 2 numbers: 53147" #"I have 2 numbers: " #"53147"))
       (#"^\\D*(?!123)" #"ABC123" (#"AB"))
       (#"^(\\D*)(?=\\d)(?!123)" #"ABC445" (#"ABC" #"ABC"))
       (#"^(\\D*)(?=\\d)(?!123)" #"ABC123" #f)
       #"^[W-]46]"
       (#"^[W-]46\\]" #"W46]789 " (#"W46]"))
       (#"^[W-]46\\]" #"-46]789" (#"-46]"))
       (#"^[W-]46\\]" #"Wall" #f)
       (#"^[W-]46\\]" #"Zebra" #f)
       (#"^[W-]46\\]" #"42" #f)
       (#"^[W-]46\\]" #"[abcd] " #f)
       (#"^[W-]46\\]" #"]abcd[" #f)
       (#"^[W-\\]46]" #"W46]789 " (#"W"))
       (#"^[W-\\]46]" #"Wall" (#"W"))
       (#"^[W-\\]46]" #"Zebra" (#"Z"))
       (#"^[W-\\]46]" #"Xylophone  " (#"X"))
       (#"^[W-\\]46]" #"42" (#"4"))
       (#"^[W-\\]46]" #"[abcd] " (#"["))
       (#"^[W-\\]46]" #"]abcd[" (#"]"))
       (#"^[W-\\]46]" #"\\\\backslash " (#"\\"))
       (#"^[W-\\]46]" #"-46]789" #f)
       (#"^[W-\\]46]" #"well" #f)
       (#"\\d\\d\\/\\d\\d\\/\\d\\d\\d\\d" #"01/01/2000" (#"01/01/2000"))
       (#"word (?:[a-zA-Z0-9]+ ){0,10}otherword" #"rd cat dog elephant mussel cow horse canary baboon snake shark otherword" #f)
       (#"word (?:[a-zA-Z0-9]+ ){0,10}otherword" #"rd cat dog elephant mussel cow horse canary baboon snake shark" #f)
       (#"word (?:[a-zA-Z0-9]+ ){0,300}otherword" #"rd cat dog elephant mussel cow horse canary baboon snake shark the quick brown fox and the lazy dog and several other words getting close to thirty by now I hope" #f)
       (#"^(a){0,0}" #"bcd" (#"" #f))
       (#"^(a){0,0}" #"abc" (#"" #f))
       (#"^(a){0,0}" #"aab     " (#"" #f))
       (#"^(a){0,1}" #"bcd" (#"" #f))
       (#"^(a){0,1}" #"abc" (#"a" #"a"))
       (#"^(a){0,1}" #"aab  " (#"a" #"a"))
       (#"^(a){0,2}" #"bcd" (#"" #f))
       (#"^(a){0,2}" #"abc" (#"a" #"a"))
       (#"^(a){0,2}" #"aab  " (#"aa" #"a"))
       (#"^(a){0,3}" #"bcd" (#"" #f))
       (#"^(a){0,3}" #"abc" (#"a" #"a"))
       (#"^(a){0,3}" #"aab" (#"aa" #"a"))
       (#"^(a){0,3}" #"aaa   " (#"aaa" #"a"))
       (#"^(a){0,}" #"bcd" (#"" #f))
       (#"^(a){0,}" #"abc" (#"a" #"a"))
       (#"^(a){0,}" #"aab" (#"aa" #"a"))
       (#"^(a){0,}" #"aaa" (#"aaa" #"a"))
       (#"^(a){0,}" #"aaaaaaaa    " (#"aaaaaaaa" #"a"))
       (#"^(a){1,1}" #"bcd" #f)
       (#"^(a){1,1}" #"abc" (#"a" #"a"))
       (#"^(a){1,1}" #"aab  " (#"a" #"a"))
       (#"^(a){1,2}" #"bcd" #f)
       (#"^(a){1,2}" #"abc" (#"a" #"a"))
       (#"^(a){1,2}" #"aab  " (#"aa" #"a"))
       (#"^(a){1,3}" #"bcd" #f)
       (#"^(a){1,3}" #"abc" (#"a" #"a"))
       (#"^(a){1,3}" #"aab" (#"aa" #"a"))
       (#"^(a){1,3}" #"aaa   " (#"aaa" #"a"))
       (#"^(a){1,}" #"bcd" #f)
       (#"^(a){1,}" #"abc" (#"a" #"a"))
       (#"^(a){1,}" #"aab" (#"aa" #"a"))
       (#"^(a){1,}" #"aaa" (#"aaa" #"a"))
       (#"^(a){1,}" #"aaaaaaaa    " (#"aaaaaaaa" #"a"))
       (#"^[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]" #"123456654321" (#"123456654321"))
       (#"^\\d\\d\\d\\d\\d\\d\\d\\d\\d\\d\\d\\d" #"123456654321 " (#"123456654321"))
       (#"^[\\d][\\d][\\d][\\d][\\d][\\d][\\d][\\d][\\d][\\d][\\d][\\d]" #"123456654321" (#"123456654321"))
       (#"^[abc]{12}" #"abcabcabcabc" (#"abcabcabcabc"))
       (#"^[a-c]{12}" #"abcabcabcabc" (#"abcabcabcabc"))
       (#"^(a|b|c){12}" #"abcabcabcabc " (#"abcabcabcabc" #"c"))
       (#"^[abcdefghijklmnopqrstuvwxy0123456789]" #"n" (#"n"))
       (#"^[abcdefghijklmnopqrstuvwxy0123456789]" #"z " #f)
       (#"abcde{0,0}" #"abcd" (#"abcd"))
       (#"abcde{0,0}" #"abce  " #f)
       (#"ab[cd]{0,0}e" #"abe" (#"abe"))
       (#"ab[cd]{0,0}e" #"abcde " #f)
       (#"ab(c){0,0}d" #"abd" (#"abd" #f))
       (#"ab(c){0,0}d" #"abcd   " #f)
       (#"a(b*)" #"a" (#"a" #""))
       (#"a(b*)" #"ab" (#"ab" #"b"))
       (#"a(b*)" #"abbbb" (#"abbbb" #"bbbb"))
       (#"a(b*)" #"bbbbb    " #f)
       (#"ab\\d{0}e" #"abe" (#"abe"))
       (#"ab\\d{0}e" #"ab1e   " #f)
       (#"\"([^\\\\\"]+|\\\\.)*\"" #"the \\\"quick\\\" brown fox" #f)
       (#"\"([^\\\\\"]+|\\\\.)*\"" #"\\\"the \\\\\\\"quick\\\\\\\" brown fox\\\" " #f)
       (#"(?i:<tr([\\w\\W\\s\\d][^<>]{0,})><TD([\\w\\W\\s\\d][^<>]{0,})>([\\d]{0,}\\.)(.*)((<BR>([\\w\\W\\s\\d][^<>]{0,})|[\\s]{0,}))<\\/a><\\/TD><TD([\\w\\W\\s\\d][^<>]{0,})>([\\w\\W\\s\\d][^<>]{0,})<\\/TD><TD([\\w\\W\\s\\d][^<>]{0,})>([\\w\\W\\s\\d][^<>]{0,})<\\/TD><\\/TR>)" #"R BGCOLOR='#DBE9E9'><TD align=left valign=top>43.<a href='joblist.cfm?JobID=94 6735&Keyword='>Word Processor<BR>(N-1286)</a></TD><TD align=left valign=top>Lega lstaff.com</TD><TD align=left valign=top>CA - Statewide</TD></TR>" #f)
       (#"^(b+?|a){1,2}?c" #"bac" (#"bac" #"a"))
       (#"^(b+?|a){1,2}?c" #"bbac" (#"bbac" #"a"))
       (#"^(b+?|a){1,2}?c" #"bbbac" (#"bbbac" #"a"))
       (#"^(b+?|a){1,2}?c" #"bbbbac" (#"bbbbac" #"a"))
       (#"^(b+?|a){1,2}?c" #"bbbbbac " (#"bbbbbac" #"a"))
       (#"^(b+|a){1,2}?c" #"bac" (#"bac" #"a"))
       (#"^(b+|a){1,2}?c" #"bbac" (#"bbac" #"a"))
       (#"^(b+|a){1,2}?c" #"bbbac" (#"bbbac" #"a"))
       (#"^(b+|a){1,2}?c" #"bbbbac" (#"bbbbac" #"a"))
       (#"^(b+|a){1,2}?c" #"bbbbbac " (#"bbbbbac" #"a"))
       (#"\x0\\{ab\\}" #"\0{ab}" (#"\0{ab}"))
       (#"(A|B)*?CD" #"CD " (#"CD" #f))
       (#"(A|B)*CD" #"CD " (#"CD" #f))
       (#"(AB)*?\\1" #"ABABAB" (#"ABAB" #"AB"))
       (#"(AB)*\\1" #"ABABAB" (#"ABABAB" #"AB"))
       #"((a{0,5}){0,5}){0,5}[c]"
       #"((a{0,5}){0,5})*[c]"
       #"((a{0,5}){0,5})*[c]"
       #"(\\b)*a"
       (#"(a)*b" #"ab" (#"ab" #"a"))
       #"(a|)*b"
       #"(a|)*b"
       #"(a|)*b"
       (#"^(?:(a)|(b))*\\1\\2$" #"abab" (#"abab" #"a" #"b"))
       (#"abc[^x]def" #"abcxabcydef" (#"abcydef"))
       (#"^(a|\\1x)*$" #"aax" (#"aax" #"ax"))
       (#"^(a|\\1x)*$" #"aaxa" (#"aaxa" #"a"))
       (#"" #"@{['']}" (#""))
       (#"^(?:(a)|(b))*$" #"ab" (#"ab" #"a" #"b"))
       (#"[\0]" #"a" #f)
       (#"[\0]" #"\0" (#"\0"))
       (#"[\1]" #"a" #f)
       (#"[\1]" #"\1" (#"\1"))
       (#"\\10()()()()()()()()()()" #"a" #f)
       (#"a(?<=)b" #"ab" (#"ab")) ;; << added "=" to pattern
       (#"(?<=qq)b*" #"aqbbbqqbb" (#"bb")) ;; << added
       (#"(?<=q?q)b*" #"aqbbbqqbb" (#"bbb")) ;; << added
       (#"()" #"a" (#"" #""))
       #"[\\x]"
       #"[\\x]"
       #"((a)*)*"
       (#"()a\\1" #"a" (#"a" #""))
       (#"a\\1()" #"a" #f)
       (#"a(?i:a)a" #"aaa" (#"aaa"))
       (#"a(?i:a)a" #"aAa" (#"aAa"))
       (#"a(?i:a)a" #"aAA" #f)
       (#"a(?i:a(?-i:a))" #"aaa" (#"aaa"))
       (#"a(?i:a(?-i:a))" #"aAa" (#"aAa"))
       (#"a(?i:a(?-i:a))" #"aAA" #f)
       #"\\x"
       #"[a-c-e]"
       #"[a-c-e]"
       #"[a-c-e]"
       #"[a-c-e]"
       #"[b-\\d]"
       #"[b-\\d]"
       #"[b-\\d]"
       #"[b-\\d]"
       #"[b-\\d]"
       #"[\\d-f]"
       #"[\\d-f]"
       #"[\\d-f]"
       #"[\\d-f]"
       #"[\\d-f]"
       (#"[-b\\d]" #"b" (#"b"))
       (#"[-b\\d]" #"c" #f)
       (#"[-b\\d]" #"d" #f)
       (#"[-b\\d]" #"-" (#"-"))
       (#"[-b\\d]" #"1" (#"1"))
       (#"[\\df-]" #"d" #f)
       (#"[\\df-]" #"e" #f)
       (#"[\\df-]" #"f" (#"f"))
       (#"[\\df-]" #"-" (#"-"))
       (#"[\\df-]" #"1" (#"1"))
       (#"[-a-c]" #"-" (#"-"))
       (#"[-a-c]" #"a" (#"a"))
       (#"[-a-c]" #"b" (#"b"))
       (#"[-a-c]" #"d" #f)
       (#"[a-c-]" #"-" (#"-"))
       (#"[a-c-]" #"a" (#"a"))
       (#"[a-c-]" #"b" (#"b"))
       (#"[a-c-]" #"d" #f)
       (#"[-]" #"a" #f)
       (#"[-]" #"-" (#"-"))
       (#"[--]" #"a" #f)
       (#"[--]" #"-" (#"-"))
       #"[---]"
       #"[--b]"
       (#"[-b-]" #"-" (#"-"))
       (#"[-b-]" #"a" #f)
       (#"[-b-]" #"c" #f)
       #"a{"
       (#"a{}" #"aaa" (#""))
       #"a{3"
       #"a{3,"
       #"a{3, 3}"
       #"a{3, 3}"
       #"a{3, 3}"
       #"a{3, 3}"
       #"a{3, 3}"
       #"a{3, 3}"
       #"\\x x"
       #"\\x x"
       #"\\x 3"
       #"\\x 3"
       #"\\x 3"
       #"\\x 3"
       #"^a{ 1}$"
       #"^a{ 1}$"
       #"^a{ 1}$"
       #"{}"
       #"{}"
       (#"|" #"x" (#""))
       (#"|x" #"x" (#""))
       (#"x|" #"x" (#"x"))
       (#"\0000" #"\0000" (#"\0\x30"))
       (#"a(?<=)b" #"ab" (#"ab"))
       (#"a(?i:b)" #"ab" (#"ab"))
       (#"a(?i:b)" #"aB" (#"aB"))
       (#"a(?i:b)" #"Ab" #f)
       #"a(?<=a){3000}a"
       #"a(){3000}a"
       #"a(?:){3000}a"
       #"a(?<=a)*a"
       #"a(?!=a)*a"
       #"a()*a"
       #"a(?:)*a"
       #"x(?<=a)*a"
       #"a(?<=(a))*\\1"
       #"a(?<=(a))*?\\1"
       #"(?=(a)\\1)*aa"
       (#"^((a|b){2,5}){2}$" #"aaabbbbb" (#"aaabbbbb" #"bbb" #"b"))
       #"^(b*|ba){1,2}bc"
       (#"^a{4,5}(?:c|a)c$" #"aaac" #f)
       (#"^a{4,5}(?:c|a)c$" #"aaaac" #f)
       #"^(a|){4,5}(?:c|a)c$"
       (#"(?m:^).abc$" #"exabc" #f)
       (#"(?m:^)abc" #"c" #f)
       (#"^abc" #"c" #f)
       (#"(?<!bar)foo" #"foo" (#"foo"))
       (#"(?<!bar)foo" #"catfood" (#"foo"))
       (#"(?<!bar)foo" #"arfootle" (#"foo"))
       (#"(?<!bar)foo" #"rfoosh" (#"foo"))
       (#"(?<!bar)foo" #"barfoo" #f)
       (#"(?<!bar)foo" #"towbarfoo" #f)
       (#"\\w{3}(?<!bar)foo" #"catfood" (#"catfoo"))
       (#"\\w{3}(?<!bar)foo" #"foo" #f)
       (#"\\w{3}(?<!bar)foo" #"barfoo" #f)
       (#"\\w{3}(?<!bar)foo" #"towbarfoo" #f)
       (#"(?<=(foo)a)bar" #"fooabar" (#"bar" #"foo"))
       (#"(?<=(foo)a)bar" #"bar" #f)
       (#"(?<=(foo)a)bar" #"foobbar" #f)
       (#"a(?<=x|ab)b" #"ab" #f)
       (#"(?>(\\.\\d\\d[1-9]?))\\d+" #"1.230003938" (#".230003938" #".23"))
       (#"(?>(\\.\\d\\d[1-9]?))\\d+" #"1.875000282" (#".875000282" #".875"))
       (#"(?>(\\.\\d\\d[1-9]?))\\d+" #"1.235 " #f)
       (#"^((?>\\w+)|(?>\\s+))*$" #"now is the time for all good men to come to the aid of the party" (#"now is the time for all good men to come to the aid of the party" #"party"))
       (#"^((?>\\w+)|(?>\\s+))*$" #"this is not a line with only words and spaces!" #f)
       (#"(\\d+)(\\w)" #"12345a" (#"12345a" #"12345" #"a"))
       (#"(\\d+)(\\w)" #"12345+ " (#"12345" #"1234" #"5"))
       (#"((?>\\d+))(\\w)" #"12345a" (#"12345a" #"12345" #"a"))
       (#"((?>\\d+))(\\w)" #"12345+ " #f)
       (#"(?>a+)b" #"aaab" (#"aaab"))
       (#"((?>a+)b)" #"aaab" (#"aaab" #"aaab"))
       (#"(?>(a+))b" #"aaab" (#"aaab" #"aaa"))
       (#"(?>b)+" #"aaabbbccc" (#"bbb"))
       (#"(?>a+|b+|c+)*c" #"aaabbbbccccd" (#"aaabbbbc"))
       (#"((?>[^()]+)|\\([^()]*\\))+" #"((abc(ade)ufh()()x" (#"abc(ade)ufh()()x" #"x"))
       (#"\\(((?>[^()]+)|\\([^()]+\\))+\\)" #"(abc)" (#"(abc)" #"abc"))
       (#"\\(((?>[^()]+)|\\([^()]+\\))+\\)" #"(abc(def)xyz)" (#"(abc(def)xyz)" #"xyz"))
       (#"\\(((?>[^()]+)|\\([^()]+\\))+\\)" #"((()aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa   " #f)
       (#"a(?i:b)c" #"abc" (#"abc"))
       (#"a(?i:b)c" #"aBc" (#"aBc"))
       (#"a(?i:b)c" #"ABC" #f)
       (#"a(?i:b)c" #"abC" #f)
       (#"a(?i:b)c" #"aBC" #f)
       (#"a(?i:b)*c" #"aBc" (#"aBc"))
       (#"a(?i:b)*c" #"aBBc" (#"aBBc"))
       (#"a(?i:b)*c" #"aBC" #f)
       (#"a(?i:b)*c" #"aBBC" #f)
       (#"a(?=b(?i:c))\\w\\wd" #"abcd" (#"abcd"))
       (#"a(?=b(?i:c))\\w\\wd" #"abCd" (#"abCd"))
       (#"a(?=b(?i:c))\\w\\wd" #"aBCd" #f)
       (#"a(?=b(?i:c))\\w\\wd" #"abcD     " #f)
       (#"(?i:(?s-i:more.*than).*million)" #"more than million" (#"more than million"))
       (#"(?i:(?s-i:more.*than).*million)" #"more than MILLION" (#"more than MILLION"))
       (#"(?i:(?s-i:more.*than).*million)" #"MORE THAN MILLION    " #f)
       (#"(?i:(?s-i:more.*than).*million)" #"more than million" (#"more than million"))
       (#"(?i:(?s-i:more.*than).*million)" #"more than MILLION" (#"more than MILLION"))
       (#"(?i:(?s-i:more.*than).*million)" #"MORE THAN MILLION    " #f)
       (#"(?>a(?i:b+))+c" #"abc" (#"abc"))
       (#"(?>a(?i:b+))+c" #"aBbc" (#"aBbc"))
       (#"(?>a(?i:b+))+c" #"aBBc " (#"aBBc"))
       (#"(?>a(?i:b+))+c" #"Abc" #f)
       (#"(?>a(?i:b+))+c" #"abAb    " #f)
       (#"(?>a(?i:b+))+c" #"abbC " #f)
       (#"(?=a(?i:b))\\w\\wc" #"abc" (#"abc"))
       (#"(?=a(?i:b))\\w\\wc" #"aBc" (#"aBc"))
       (#"(?=a(?i:b))\\w\\wc" #"Ab " #f)
       (#"(?=a(?i:b))\\w\\wc" #"abC" #f)
       (#"(?=a(?i:b))\\w\\wc" #"aBC     " #f)
       (#"(?<=a(?i:b))(\\w\\w)c" #"abxxc" (#"xxc" #"xx"))
       (#"(?<=a(?i:b))(\\w\\w)c" #"aBxxc" (#"xxc" #"xx"))
       (#"(?<=a(?i:b))(\\w\\w)c" #"Abxxc" #f)
       (#"(?<=a(?i:b))(\\w\\w)c" #"ABxxc" #f)
       (#"(?<=a(?i:b))(\\w\\w)c" #"abxxC      " #f)
       (#"(?i:(blah))\\s+\\1" #"blah blah" (#"blah blah" #"blah"))
       (#"(?i:(blah))\\s+\\1" #"BLAH BLAH" (#"BLAH BLAH" #"BLAH"))
       (#"(?i:(blah))\\s+\\1" #"Blah Blah" (#"Blah Blah" #"Blah"))
       (#"(?i:(blah))\\s+\\1" #"blaH blaH" (#"blaH blaH" #"blaH"))
       (#"(?i:(blah))\\s+\\1" #"blah BLAH" #f)
       (#"(?i:(blah))\\s+\\1" #"Blah blah      " #f)
       (#"(?i:(blah))\\s+\\1" #"blaH blah " #f)
       (#"(?i:(blah))\\s+(?i:\\1)" #"blah blah" (#"blah blah" #"blah"))
       (#"(?i:(blah))\\s+(?i:\\1)" #"BLAH BLAH" (#"BLAH BLAH" #"BLAH"))
       (#"(?i:(blah))\\s+(?i:\\1)" #"Blah Blah" (#"Blah Blah" #"Blah"))
       (#"(?i:(blah))\\s+(?i:\\1)" #"blaH blaH" (#"blaH blaH" #"blaH"))
       (#"(?i:(blah))\\s+(?i:\\1)" #"blah BLAH" (#"blah BLAH" #"blah"))
       (#"(?i:(blah))\\s+(?i:\\1)" #"Blah blah      " (#"Blah blah" #"Blah"))
       (#"(?i:(blah))\\s+(?i:\\1)" #"blaH blah " (#"blaH blah" #"blaH"))
       #"(?>a*)*"
       #"(abc|)+"
       #"([a]*)*"
       #"([ab]*)*"
       #"([^a]*)*"
       #"([^ab]*)*"
       #"([a]*?)*"
       #"([ab]*?)*"
       #"([^a]*?)*"
       #"([^ab]*?)*"
       #"([^ab]*?)*"
       #"(?>a*)*"
       #"(?>a*)*"
       #"((?>a*))*"
       #"((?>a*?))*"
       (#"(?<=(foo))bar\\1" #"foobarfoo" (#"barfoo" #"foo"))
       (#"(?<=(foo))bar\\1" #"foobarfootling " (#"barfoo" #"foo"))
       (#"(?<=(foo))bar\\1" #"foobar" #f)
       (#"(?<=(foo))bar\\1" #"barfoo   " #f)
       (#"(?i:saturday|sunday)" #"saturday" (#"saturday"))
       (#"(?i:saturday|sunday)" #"sunday" (#"sunday"))
       (#"(?i:saturday|sunday)" #"Saturday" (#"Saturday"))
       (#"(?i:saturday|sunday)" #"Sunday" (#"Sunday"))
       (#"(?i:saturday|sunday)" #"SATURDAY" (#"SATURDAY"))
       (#"(?i:saturday|sunday)" #"SUNDAY" (#"SUNDAY"))
       (#"(?i:saturday|sunday)" #"SunDay" (#"SunDay"))
       (#"(a(?i:bc)|(?i:BB))x" #"abcx" (#"abcx" #"abc"))
       (#"(a(?i:bc)|(?i:BB))x" #"aBCx" (#"aBCx" #"aBC"))
       (#"(a(?i:bc)|(?i:BB))x" #"bbx" (#"bbx" #"bb"))
       (#"(a(?i:bc)|(?i:BB))x" #"BBx" (#"BBx" #"BB"))
       (#"(a(?i:bc)|(?i:BB))x" #"abcX" #f)
       (#"(a(?i:bc)|(?i:BB))x" #"aBCX" #f)
       (#"(a(?i:bc)|(?i:BB))x" #"bbX" #f)
       (#"(a(?i:bc)|(?i:BB))x" #"BBX" #f)
       (#"^([ab](?i:[cd])|(?i:[ef]))" #"ac" (#"ac" #"ac"))
       (#"^([ab](?i:[cd])|(?i:[ef]))" #"aC" (#"aC" #"aC"))
       (#"^([ab](?i:[cd])|(?i:[ef]))" #"bD" (#"bD" #"bD"))
       (#"^([ab](?i:[cd])|(?i:[ef]))" #"elephant" (#"e" #"e"))
       (#"^([ab](?i:[cd])|(?i:[ef]))" #"Europe " (#"E" #"E"))
       (#"^([ab](?i:[cd])|(?i:[ef]))" #"frog" (#"f" #"f"))
       (#"^([ab](?i:[cd])|(?i:[ef]))" #"France" (#"F" #"F"))
       (#"^([ab](?i:[cd])|(?i:[ef]))" #"Africa     " #f)
       (#"^(ab|a(?i:[b-c](?m-i:d))|(?m-i:x(?i:y))|(?i:z))" #"ab" (#"ab" #"ab"))
       (#"^(ab|a(?i:[b-c](?m-i:d))|(?m-i:x(?i:y))|(?i:z))" #"aBd" (#"aBd" #"aBd"))
       (#"^(ab|a(?i:[b-c](?m-i:d))|(?m-i:x(?i:y))|(?i:z))" #"xy" (#"xy" #"xy"))
       (#"^(ab|a(?i:[b-c](?m-i:d))|(?m-i:x(?i:y))|(?i:z))" #"xY" (#"xY" #"xY"))
       (#"^(ab|a(?i:[b-c](?m-i:d))|(?m-i:x(?i:y))|(?i:z))" #"zebra" (#"z" #"z"))
       (#"^(ab|a(?i:[b-c](?m-i:d))|(?m-i:x(?i:y))|(?i:z))" #"Zambesi" (#"Z" #"Z"))
       (#"^(ab|a(?i:[b-c](?m-i:d))|(?m-i:x(?i:y))|(?i:z))" #"aCD  " #f)
       (#"^(ab|a(?i:[b-c](?m-i:d))|(?m-i:x(?i:y))|(?i:z))" #"XY  " #f)
       (#"(?<=(?<!foo)bar)baz" #"barbaz" (#"baz"))
       (#"(?<=(?<!foo)bar)baz" #"barbarbaz " (#"baz"))
       (#"(?<=(?<!foo)bar)baz" #"koobarbaz " (#"baz"))
       (#"(?<=(?<!foo)bar)baz" #"baz" #f)
       (#"(?<=(?<!foo)bar)baz" #"foobarbaz " #f)
       (#"^(a\\1?){4}$" #"a" #f)
       (#"^(a\\1?){4}$" #"aa" #f)
       (#"^(a\\1?){4}$" #"aaa" #f)
       (#"^(a\\1?){4}$" #"aaaa" (#"aaaa" #"a"))
       (#"^(a\\1?){4}$" #"aaaaa" (#"aaaaa" #"a"))
       (#"^(a\\1?){4}$" #"aaaaaa" (#"aaaaaa" #"aa"))
       (#"^(a\\1?){4}$" #"aaaaaaa" (#"aaaaaaa" #"a"))
       (#"^(a\\1?){4}$" #"aaaaaaaa" #f)
       (#"^(a\\1?){4}$" #"aaaaaaaaa" #f)
       (#"^(a\\1?){4}$" #"aaaaaaaaaa" (#"aaaaaaaaaa" #"aaaa"))
       (#"^(a\\1?){4}$" #"aaaaaaaaaaa" #f)
       (#"^(a\\1?){4}$" #"aaaaaaaaaaaa" #f)
       (#"^(a\\1?){4}$" #"aaaaaaaaaaaaa" #f)
       (#"^(a\\1?){4}$" #"aaaaaaaaaaaaaa" #f)
       (#"^(a\\1?){4}$" #"aaaaaaaaaaaaaaa" #f)
       (#"^(a\\1?){4}$" #"aaaaaaaaaaaaaaaa               " #f)
       (#"^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$" #"a" #f)
       (#"^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$" #"aa" #f)
       (#"^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$" #"aaa" #f)
       (#"^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$" #"aaaa" (#"aaaa" #"a" #"a" #"a" #"a"))
       (#"^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$" #"aaaaa" (#"aaaaa" #"a" #"aa" #"a" #"a"))
       (#"^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$" #"aaaaaa" (#"aaaaaa" #"a" #"aa" #"a" #"aa"))
       (#"^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$" #"aaaaaaa" (#"aaaaaaa" #"a" #"aa" #"aaa" #"a"))
       (#"^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$" #"aaaaaaaa" #f)
       (#"^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$" #"aaaaaaaaa" #f)
       (#"^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$" #"aaaaaaaaaa" (#"aaaaaaaaaa" #"a" #"aa" #"aaa" #"aaaa"))
       (#"^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$" #"aaaaaaaaaaa" #f)
       (#"^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$" #"aaaaaaaaaaaa" #f)
       (#"^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$" #"aaaaaaaaaaaaa" #f)
       (#"^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$" #"aaaaaaaaaaaaaa" #f)
       (#"^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$" #"aaaaaaaaaaaaaaa" #f)
       (#"^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$" #"aaaaaaaaaaaaaaaa               " #f)
       (#"abc" #"abc" (#"abc"))
       (#"abc" #"xabcy" (#"abc"))
       (#"abc" #"ababc" (#"abc"))
       (#"abc" #"xbc" #f)
       (#"abc" #"axc" #f)
       (#"abc" #"abx" #f)
       (#"ab*c" #"abc" (#"abc"))
       (#"ab*bc" #"abc" (#"abc"))
       (#"ab*bc" #"abbc" (#"abbc"))
       (#"ab*bc" #"abbbbc" (#"abbbbc"))
       (#".{1}" #"abbbbc" (#"a"))
       (#".{3,4}" #"abbbbc" (#"abbb"))
       (#"ab{0,}bc" #"abbbbc" (#"abbbbc"))
       (#"ab+bc" #"abbc" (#"abbc"))
       (#"ab+bc" #"abc" #f)
       (#"ab+bc" #"abq" #f)
       (#"ab+bc" #"abbbbc" (#"abbbbc"))
       (#"ab{1,}bc" #"abbbbc" (#"abbbbc"))
       (#"ab{1,3}bc" #"abbbbc" (#"abbbbc"))
       (#"ab{3,4}bc" #"abbbbc" (#"abbbbc"))
       (#"ab{4,5}bc" #"abq" #f)
       (#"ab{4,5}bc" #"abbbbc" #f)
       (#"ab?bc" #"abbc" (#"abbc"))
       (#"ab?bc" #"abc" (#"abc"))
       (#"ab{0,1}bc" #"abc" (#"abc"))
       (#"ab?c" #"abc" (#"abc"))
       (#"ab{0,1}c" #"abc" (#"abc"))
       (#"^abc$" #"abc" (#"abc"))
       (#"^abc$" #"abbbbc" #f)
       (#"^abc$" #"abcc" #f)
       (#"^abc" #"abcc" (#"abc"))
       (#"abc$" #"aabc" (#"abc"))
       (#"abc$" #"aabc" (#"abc"))
       (#"abc$" #"aabcd" #f)
       (#"^" #"abc" (#""))
       (#"$" #"abc" (#""))
       (#"a.c" #"abc" (#"abc"))
       (#"a.c" #"axc" (#"axc"))
       (#"a.*c" #"axyzc" (#"axyzc"))
       (#"a[bc]d" #"abd" (#"abd"))
       (#"a[bc]d" #"axyzd" #f)
       (#"a[bc]d" #"abc" #f)
       (#"a[b-d]e" #"ace" (#"ace"))
       (#"a[b-d]" #"aac" (#"ac"))
       (#"a[-b]" #"a-" (#"a-"))
       (#"a[b-]" #"a-" (#"a-"))
       #"a]"
       (#"a[]]" #"a]" (#"a]"))
       (#"a[]]b" #"a]b" (#"a]b"))
       (#"a[^bc]d" #"aed" (#"aed"))
       (#"a[^bc]d" #"abd" #f)
       (#"a[^bc]d" #"abd" #f)
       (#"a[^-b]c" #"adc" (#"adc"))
       (#"a[^]b]c" #"adc" (#"adc"))
       (#"a[^]b]c" #"a-c" (#"a-c"))
       (#"a[^]b]c" #"a]c" #f)
       (#"\\ba\\b" #"a-" (#"a"))
       (#"\\ba\\b" #"-a" (#"a"))
       (#"\\ba\\b" #"-a-" (#"a"))
       (#"\\by\\b" #"xy" #f)
       (#"\\by\\b" #"yz" #f)
       (#"\\by\\b" #"xyz" #f)
       (#"\\Ba\\B" #"a-" #f)
       (#"\\Ba\\B" #"-a" #f)
       (#"\\Ba\\B" #"-a-" #f)
       (#"\\By\\b" #"xy" (#"y"))
       (#"\\by\\B" #"yz" (#"y"))
       (#"\\By\\B" #"xyz" (#"y"))
       (#"\\w" #"a" (#"a"))
       (#"\\W" #"-" (#"-"))
       (#"\\W" #"-" (#"-"))
       (#"\\W" #"a" #f)
       (#"a\\sb" #"a b" (#"a b"))
       (#"a\\Sb" #"a-b" (#"a-b"))
       (#"a\\Sb" #"a-b" (#"a-b"))
       (#"a\\Sb" #"a b" #f)
       (#"\\d" #"1" (#"1"))
       (#"\\D" #"-" (#"-"))
       (#"\\D" #"-" (#"-"))
       (#"\\D" #"1" #f)
       (#"[\\w]" #"a" (#"a"))
       (#"[\\W]" #"-" (#"-"))
       (#"[\\W]" #"-" (#"-"))
       (#"[\\W]" #"a" #f)
       (#"a[\\s]b" #"a b" (#"a b"))
       (#"a[\\S]b" #"a-b" (#"a-b"))
       (#"a[\\S]b" #"a-b" (#"a-b"))
       (#"a[\\S]b" #"a b" #f)
       (#"[\\d]" #"1" (#"1"))
       (#"[\\D]" #"-" (#"-"))
       (#"[\\D]" #"-" (#"-"))
       (#"[\\D]" #"1" #f)
       (#"ab|cd" #"abc" (#"ab"))
       (#"ab|cd" #"abcd" (#"ab"))
       (#"()ef" #"def" (#"ef" #""))
       (#"a\\(b" #"a(b" (#"a(b"))
       (#"a\\(*b" #"ab" (#"ab"))
       (#"a\\(*b" #"a((b" (#"a((b"))
       (#"a\\\\b" #"a\\b" (#"a\\b"))
       (#"((a))" #"abc" (#"a" #"a" #"a"))
       (#"(a)b(c)" #"abc" (#"abc" #"a" #"c"))
       (#"a+b+c" #"aabbabc" (#"abc"))
       (#"a{1,}b{1,}c" #"aabbabc" (#"abc"))
       (#"a.+?c" #"abcabc" (#"abc"))
       (#"(a+|b)*" #"ab" (#"ab" #"b"))
       (#"(a+|b){0,}" #"ab" (#"ab" #"b"))
       (#"(a+|b)+" #"ab" (#"ab" #"b"))
       (#"(a+|b){1,}" #"ab" (#"ab" #"b"))
       (#"(a+|b)?" #"ab" (#"a" #"a"))
       (#"(a+|b){0,1}" #"ab" (#"a" #"a"))
       (#"[^ab]*" #"cde" (#"cde"))
       (#"abc" #"b" #f)
       (#"([abc])*d" #"abbbcd" (#"abbbcd" #"c"))
       (#"([abc])*bcd" #"abcd" (#"abcd" #"a"))
       (#"a|b|c|d|e" #"e" (#"e"))
       (#"(a|b|c|d|e)f" #"ef" (#"ef" #"e"))
       (#"abcd*efg" #"abcdefg" (#"abcdefg"))
       (#"ab*" #"xabyabbbz" (#"ab"))
       (#"ab*" #"xayabbbz" (#"a"))
       (#"(ab|cd)e" #"abcde" (#"cde" #"cd"))
       (#"[abhgefdc]ij" #"hij" (#"hij"))
       (#"(abc|)ef" #"abcdef" (#"ef" #""))
       (#"(a|b)c*d" #"abcd" (#"bcd" #"b"))
       (#"(ab|ab*)bc" #"abc" (#"abc" #"a"))
       (#"a([bc]*)c*" #"abc" (#"abc" #"bc"))
       (#"a([bc]*)(c*d)" #"abcd" (#"abcd" #"bc" #"d"))
       (#"a([bc]+)(c*d)" #"abcd" (#"abcd" #"bc" #"d"))
       (#"a([bc]*)(c+d)" #"abcd" (#"abcd" #"b" #"cd"))
       (#"a[bcd]*dcdcde" #"adcdcde" (#"adcdcde"))
       (#"a[bcd]+dcdcde" #"abcde" #f)
       (#"a[bcd]+dcdcde" #"adcdcde" #f)
       (#"(ab|a)b*c" #"abc" (#"abc" #"ab"))
       (#"((a)(b)c)(d)" #"abcd" (#"abcd" #"abc" #"a" #"b" #"d"))
       (#"[a-zA-Z_][a-zA-Z0-9_]*" #"alpha" (#"alpha"))
       (#"^a(bc+|b[eh])g|.h$" #"abh" (#"bh" #f))
       (#"(bc+d$|ef*g.|h?i(j|k))" #"effgz" (#"effgz" #"effgz" #f))
       (#"(bc+d$|ef*g.|h?i(j|k))" #"ij" (#"ij" #"ij" #"j"))
       (#"(bc+d$|ef*g.|h?i(j|k))" #"reffgz" (#"effgz" #"effgz" #f))
       (#"(bc+d$|ef*g.|h?i(j|k))" #"effg" #f)
       (#"(bc+d$|ef*g.|h?i(j|k))" #"bcdd" #f)
       (#"((((((((((a))))))))))" #"a" (#"a" #"a" #"a" #"a" #"a" #"a" #"a" #"a" #"a" #"a" #"a"))
       (#"((((((((((a))))))))))\\10" #"aa" (#"aa" #"a" #"a" #"a" #"a" #"a" #"a" #"a" #"a" #"a" #"a"))
       (#"(((((((((a)))))))))" #"a" (#"a" #"a" #"a" #"a" #"a" #"a" #"a" #"a" #"a" #"a"))
       (#"multiple words of text" #"aa" #f)
       (#"multiple words of text" #"uh-uh" #f)
       (#"multiple words" #"multiple words, yeah" (#"multiple words"))
       (#"(.*)c(.*)" #"abcde" (#"abcde" #"ab" #"de"))
       (#"\\((.*), (.*)\\)" #"(a, b)" (#"(a, b)" #"a" #"b"))
       (#"abcd" #"abcd" (#"abcd"))
       (#"a(bc)d" #"abcd" (#"abcd" #"bc"))
       (#"a[-]?c" #"ac" (#"ac"))
       (#"(abc)\\1" #"abcabc" (#"abcabc" #"abc"))
       (#"([a-c]*)\\1" #"abcabc" (#"abcabc" #"abc"))
       (#"(a)|\\1" #"a" (#"a" #"a"))
       (#"(a)|\\1" #"ab" (#"a" #"a"))
       (#"(a)|\\1" #"x" #f)
       (#"(([a-c])b*?\\2)*" #"ababbbcbc" (#"ababb" #"bb" #"b"))
       (#"(([a-c])b*?\\2){3}" #"ababbbcbc" (#"ababbbcbc" #"cbc" #"c"))
       (#"((\\3|b)\\2(a)x)+" #"aaaxabaxbaaxbbax" (#"bbax" #"bbax" #"b" #"a"))
       (#"((\\3|b)\\2(a)){2,}" #"bbaababbabaaaaabbaaaabba" (#"bbaaaabba" #"bba" #"b" #"a"))
       (#"(?i:abc)" #"ABC" (#"ABC"))
       (#"(?i:abc)" #"XABCY" (#"ABC"))
       (#"(?i:abc)" #"ABABC" (#"ABC"))
       (#"(?i:abc)" #"aaxabxbaxbbx" #f)
       (#"(?i:abc)" #"XBC" #f)
       (#"(?i:abc)" #"AXC" #f)
       (#"(?i:abc)" #"ABX" #f)
       (#"(?i:ab*c)" #"ABC" (#"ABC"))
       (#"(?i:ab*bc)" #"ABC" (#"ABC"))
       (#"(?i:ab*bc)" #"ABBC" (#"ABBC"))
       (#"(?i:ab*?bc)" #"ABBBBC" (#"ABBBBC"))
       (#"(?i:ab{0,}?bc)" #"ABBBBC" (#"ABBBBC"))
       (#"(?i:ab+?bc)" #"ABBC" (#"ABBC"))
       (#"(?i:ab+bc)" #"ABC" #f)
       (#"(?i:ab+bc)" #"ABQ" #f)
       (#"(?i:ab+bc)" #"ABBBBC" (#"ABBBBC"))
       (#"(?i:ab{1,}?bc)" #"ABBBBC" (#"ABBBBC"))
       (#"(?i:ab{1,3}?bc)" #"ABBBBC" (#"ABBBBC"))
       (#"(?i:ab{3,4}?bc)" #"ABBBBC" (#"ABBBBC"))
       (#"(?i:ab{4,5}?bc)" #"ABQ" #f)
       (#"(?i:ab{4,5}?bc)" #"ABBBBC" #f)
       (#"(?i:ab??bc)" #"ABBC" (#"ABBC"))
       (#"(?i:ab??bc)" #"ABC" (#"ABC"))
       (#"(?i:ab{0,1}?bc)" #"ABC" (#"ABC"))
       (#"(?i:ab??c)" #"ABC" (#"ABC"))
       (#"(?i:ab{0,1}?c)" #"ABC" (#"ABC"))
       (#"(?i:^abc$)" #"ABC" (#"ABC"))
       (#"(?i:^abc$)" #"ABBBBC" #f)
       (#"(?i:^abc$)" #"ABCC" #f)
       (#"(?i:^abc)" #"ABCC" (#"ABC"))
       (#"(?i:abc$)" #"AABC" (#"ABC"))
       (#"(?i:^)" #"ABC" (#""))
       (#"(?i:$)" #"ABC" (#""))
       (#"(?i:a.c)" #"ABC" (#"ABC"))
       (#"(?i:a.c)" #"AXC" (#"AXC"))
       (#"(?i:a.*?c)" #"AXYZC" (#"AXYZC"))
       (#"(?i:a.*c)" #"AABC" (#"AABC"))
       (#"(?i:a.*c)" #"AXYZD" #f)
       (#"(?i:a[bc]d)" #"ABD" (#"ABD"))
       (#"(?i:a[b-d]e)" #"ACE" (#"ACE"))
       (#"(?i:a[b-d]e)" #"ABC" #f)
       (#"(?i:a[b-d]e)" #"ABD" #f)
       (#"(?i:a[b-d])" #"AAC" (#"AC"))
       (#"(?i:a[-b])" #"A-" (#"A-"))
       (#"(?i:a[b-])" #"A-" (#"A-"))
       #"(?i:a])"
       (#"(?i:a[]])" #"A]" (#"A]"))
       (#"(?i:a[]]b)" #"A]B" (#"A]B"))
       (#"(?i:a[^bc]d)" #"AED" (#"AED"))
       (#"(?i:a[^-b]c)" #"ADC" (#"ADC"))
       (#"(?i:a[^-b]c)" #"ABD" #f)
       (#"(?i:a[^-b]c)" #"A-C" #f)
       (#"(?i:a[^]b]c)" #"ADC" (#"ADC"))
       (#"(?i:ab|cd)" #"ABC" (#"AB"))
       (#"(?i:ab|cd)" #"ABCD" (#"AB"))
       (#"(?i:()ef)" #"DEF" (#"EF" #""))
       (#"(?i:$b)" #"A]C" #f)
       (#"(?i:$b)" #"B" #f)
       (#"(?i:a\\(b)" #"A(B" (#"A(B"))
       (#"(?i:a\\(*b)" #"AB" (#"AB"))
       (#"(?i:a\\(*b)" #"A((B" (#"A((B"))
       (#"(?i:a\\\\b)" #"A\\B" (#"A\\B"))
       (#"(?i:((a)))" #"ABC" (#"A" #"A" #"A"))
       (#"(?i:(a)b(c))" #"ABC" (#"ABC" #"A" #"C"))
       (#"(?i:a+b+c)" #"AABBABC" (#"ABC"))
       (#"(?i:a{1,}b{1,}c)" #"AABBABC" (#"ABC"))
       (#"(?i:a.+?c)" #"ABCABC" (#"ABC"))
       (#"(?i:a.*?c)" #"ABCABC" (#"ABC"))
       (#"(?i:a.{0,5}?c)" #"ABCABC" (#"ABC"))
       (#"(?i:(a+|b)*)" #"AB" (#"AB" #"B"))
       (#"(?i:(a+|b){0,})" #"AB" (#"AB" #"B"))
       (#"(?i:(a+|b)+)" #"AB" (#"AB" #"B"))
       (#"(?i:(a+|b){1,})" #"AB" (#"AB" #"B"))
       (#"(?i:(a+|b)?)" #"AB" (#"A" #"A"))
       (#"(?i:(a+|b){0,1})" #"AB" (#"A" #"A"))
       (#"(?i:(a+|b){0,1}?)" #"AB" (#"" #f))
       (#"(?i:[^ab]*)" #"CDE" (#"CDE"))
       (#"(?i:([abc])*d)" #"ABBBCD" (#"ABBBCD" #"C"))
       (#"(?i:([abc])*bcd)" #"ABCD" (#"ABCD" #"A"))
       (#"(?i:a|b|c|d|e)" #"E" (#"E"))
       (#"(?i:(a|b|c|d|e)f)" #"EF" (#"EF" #"E"))
       (#"(?i:abcd*efg)" #"ABCDEFG" (#"ABCDEFG"))
       (#"(?i:ab*)" #"XABYABBBZ" (#"AB"))
       (#"(?i:ab*)" #"XAYABBBZ" (#"A"))
       (#"(?i:(ab|cd)e)" #"ABCDE" (#"CDE" #"CD"))
       (#"(?i:[abhgefdc]ij)" #"HIJ" (#"HIJ"))
       (#"(?i:^(ab|cd)e)" #"ABCDE" #f)
       (#"(?i:(abc|)ef)" #"ABCDEF" (#"EF" #""))
       (#"(?i:(a|b)c*d)" #"ABCD" (#"BCD" #"B"))
       (#"(?i:(ab|ab*)bc)" #"ABC" (#"ABC" #"A"))
       (#"(?i:a([bc]*)c*)" #"ABC" (#"ABC" #"BC"))
       (#"(?i:a([bc]*)(c*d))" #"ABCD" (#"ABCD" #"BC" #"D"))
       (#"(?i:a([bc]+)(c*d))" #"ABCD" (#"ABCD" #"BC" #"D"))
       (#"(?i:a([bc]*)(c+d))" #"ABCD" (#"ABCD" #"B" #"CD"))
       (#"(?i:a[bcd]*dcdcde)" #"ADCDCDE" (#"ADCDCDE"))
       (#"(?i:(ab|a)b*c)" #"ABC" (#"ABC" #"AB"))
       (#"(?i:((a)(b)c)(d))" #"ABCD" (#"ABCD" #"ABC" #"A" #"B" #"D"))
       (#"(?i:[a-zA-Z_][a-zA-Z0-9_]*)" #"ALPHA" (#"ALPHA"))
       (#"(?i:^a(bc+|b[eh])g|.h$)" #"ABH" (#"BH" #f))
       (#"(?i:(bc+d$|ef*g.|h?i(j|k)))" #"EFFGZ" (#"EFFGZ" #"EFFGZ" #f))
       (#"(?i:(bc+d$|ef*g.|h?i(j|k)))" #"IJ" (#"IJ" #"IJ" #"J"))
       (#"(?i:(bc+d$|ef*g.|h?i(j|k)))" #"REFFGZ" (#"EFFGZ" #"EFFGZ" #f))
       (#"(?i:(bc+d$|ef*g.|h?i(j|k)))" #"ADCDCDE" #f)
       (#"(?i:(bc+d$|ef*g.|h?i(j|k)))" #"EFFG" #f)
       (#"(?i:(bc+d$|ef*g.|h?i(j|k)))" #"BCDD" #f)
       (#"(?i:((((((((((a)))))))))))" #"A" (#"A" #"A" #"A" #"A" #"A" #"A" #"A" #"A" #"A" #"A" #"A"))
       (#"(?i:((((((((((a))))))))))\\10)" #"AA" (#"AA" #"A" #"A" #"A" #"A" #"A" #"A" #"A" #"A" #"A" #"A"))
       (#"(?i:(((((((((a))))))))))" #"A" (#"A" #"A" #"A" #"A" #"A" #"A" #"A" #"A" #"A" #"A"))
       (#"(?i:(?:(?:(?:(?:(?:(?:(?:(?:(?:(a)))))))))))" #"A" (#"A" #"A"))
       (#"(?i:(?:(?:(?:(?:(?:(?:(?:(?:(?:(a|b|c)))))))))))" #"C" (#"C" #"C"))
       (#"(?i:multiple words of text)" #"AA" #f)
       (#"(?i:multiple words of text)" #"UH-UH" #f)
       (#"(?i:multiple words)" #"MULTIPLE WORDS, YEAH" (#"MULTIPLE WORDS"))
       (#"(?i:(.*)c(.*))" #"ABCDE" (#"ABCDE" #"AB" #"DE"))
       (#"(?i:\\((.*), (.*)\\))" #"(A, B)" (#"(A, B)" #"A" #"B"))
       (#"(?i:abcd)" #"ABCD" (#"ABCD"))
       (#"(?i:a(bc)d)" #"ABCD" (#"ABCD" #"BC"))
       (#"(?i:a[-]?c)" #"AC" (#"AC"))
       (#"(?i:(abc)\\1)" #"ABCABC" (#"ABCABC" #"ABC"))
       (#"(?i:([a-c]*)\\1)" #"ABCABC" (#"ABCABC" #"ABC"))
       (#"a(?!b)." #"abad" (#"ad"))
       (#"a(?=d)." #"abad" (#"ad"))
       (#"a(?=c|d)." #"abad" (#"ad"))
       (#"a(?:b|c|d)(.)" #"ace" (#"ace" #"e"))
       (#"a(?:b|c|d)*(.)" #"ace" (#"ace" #"e"))
       (#"a(?:b|c|d)+?(.)" #"ace" (#"ace" #"e"))
       (#"a(?:b|c|d)+?(.)" #"acdbcdbe" (#"acd" #"d"))
       (#"a(?:b|c|d)+(.)" #"acdbcdbe" (#"acdbcdbe" #"e"))
       (#"a(?:b|c|d){2}(.)" #"acdbcdbe" (#"acdb" #"b"))
       (#"a(?:b|c|d){4,5}(.)" #"acdbcdbe" (#"acdbcdb" #"b"))
       (#"a(?:b|c|d){4,5}?(.)" #"acdbcdbe" (#"acdbcd" #"d"))
       (#"((foo)|(bar))*" #"foobar" (#"foobar" #"bar" #"foo" #"bar"))
       (#"a(?:b|c|d){6,7}(.)" #"acdbcdbe" (#"acdbcdbe" #"e"))
       (#"a(?:b|c|d){6,7}?(.)" #"acdbcdbe" (#"acdbcdbe" #"e"))
       (#"a(?:b|c|d){5,6}(.)" #"acdbcdbe" (#"acdbcdbe" #"e"))
       (#"a(?:b|c|d){5,6}?(.)" #"acdbcdbe" (#"acdbcdb" #"b"))
       (#"a(?:b|c|d){5,7}(.)" #"acdbcdbe" (#"acdbcdbe" #"e"))
       (#"a(?:b|c|d){5,7}?(.)" #"acdbcdbe" (#"acdbcdb" #"b"))
       (#"a(?:b|(c|e){1,2}?|d)+?(.)" #"ace" (#"ace" #"c" #"e"))
       (#"^(.+)?B" #"AB" (#"AB" #"A"))
       (#"^([^a-z])|(\\^)$" #"." (#"." #"." #f))
       (#"^[<>]&" #"<&OUT" (#"<&"))
       (#"^(a\\1?){4}$" #"aaaaaaaaaa" (#"aaaaaaaaaa" #"aaaa"))
       (#"^(a\\1?){4}$" #"AB" #f)
       (#"^(a\\1?){4}$" #"aaaaaaaaa" #f)
       (#"^(a\\1?){4}$" #"aaaaaaaaaaa" #f)
       (#"(?:(f)(o)(o)|(b)(a)(r))*" #"foobar" (#"foobar" #"f" #"o" #"o" #"b" #"a" #"r"))
       (#"(?<=a)b" #"ab" (#"b"))
       (#"(?<=a)b" #"cb" #f)
       (#"(?<=a)b" #"b" #f)
       (#"(?<!c)b" #"ab" (#"b"))
       (#"(?<!c)b" #"b" (#"b"))
       (#"(?<!c)b" #"b" (#"b"))
       (#"(?:..)*a" #"aba" (#"aba"))
       (#"(?:..)*?a" #"aba" (#"a"))
       (#"^(?:b|a(?=(.)))*\\1" #"abc" (#"ab" #"b"))
       #"^(){3,5}"
       (#"^(a+)*ax" #"aax" (#"aax" #"a"))
       (#"^((a|b)+)*ax" #"aax" (#"aax" #"a" #"a"))
       (#"^((a|bc)+)*ax" #"aax" (#"aax" #"a" #"a"))
       (#"(a|x)*ab" #"cab" (#"ab" #f))
       (#"(a)*ab" #"cab" (#"ab" #f))
       (#"(?:(?i:a))b" #"ab" (#"ab"))
       (#"((?i:a))b" #"ab" (#"ab" #"a"))
       (#"(?:(?i:a))b" #"Ab" (#"Ab"))
       (#"((?i:a))b" #"Ab" (#"Ab" #"A"))
       (#"(?:(?i:a))b" #"cb" #f)
       (#"(?:(?i:a))b" #"aB" #f)
       (#"(?i:a)b" #"ab" (#"ab"))
       (#"((?i:a))b" #"ab" (#"ab" #"a"))
       (#"(?i:a)b" #"Ab" (#"Ab"))
       (#"((?i:a))b" #"Ab" (#"Ab" #"A"))
       (#"(?i:a)b" #"aB" #f)
       (#"(?i:a)b" #"aB" #f)
       (#"(?i:(?:(?-i:a))b)" #"ab" (#"ab"))
       (#"(?i:((?-i:a))b)" #"ab" (#"ab" #"a"))
       (#"(?i:(?:(?-i:a))b)" #"aB" (#"aB"))
       (#"(?i:((?-i:a))b)" #"aB" (#"aB" #"a"))
       (#"(?i:(?:(?-i:a))b)" #"aB" (#"aB"))
       (#"(?i:(?:(?-i:a))b)" #"Ab" #f)
       (#"(?i:(?:(?-i:a))b)" #"aB" (#"aB"))
       (#"(?i:((?-i:a))b)" #"aB" (#"aB" #"a"))
       (#"(?i:(?:(?-i:a))b)" #"Ab" #f)
       (#"(?i:(?:(?-i:a))b)" #"AB" #f)
       (#"(?i:(?-i:a)b)" #"ab" (#"ab"))
       (#"(?i:((?-i:a))b)" #"ab" (#"ab" #"a"))
       (#"(?i:(?-i:a)b)" #"aB" (#"aB"))
       (#"(?i:((?-i:a))b)" #"aB" (#"aB" #"a"))
       (#"(?i:(?-i:a)b)" #"AB" #f)
       (#"(?i:(?-i:a)b)" #"Ab" #f)
       (#"(?i:(?-i:a)b)" #"aB" (#"aB"))
       (#"(?i:((?-i:a))b)" #"aB" (#"aB" #"a"))
       (#"(?i:(?-i:a)b)" #"Ab" #f)
       (#"(?i:(?-i:a)b)" #"AB" #f)
       (#"(?i:((?-i:a.))b)" #"AB" #f)
       (#"(?:c|d)(?:)(?:a(?:)(?:b)(?:b(?:))(?:b(?:)(?:b)))" #"cabbbb" (#"cabbbb"))
       (#"(?:c|d)(?:)(?:aaaaaaaa(?:)(?:bbbbbbbb)(?:bbbbbbbb(?:))(?:bbbbbbbb(?:)(?:bbbbbbbb)))" #"caaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" (#"caaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"))
       (#"(?i:(ab)\\d\\1)" #"Ab4ab" (#"Ab4ab" #"Ab"))
       (#"(?i:(ab)\\d\\1)" #"ab4Ab" (#"ab4Ab" #"ab"))
       (#"foo\\w*\\d{4}baz" #"foobar1234baz" (#"foobar1234baz"))
       (#"x(~~)*(?:(?:F)?)?" #"x~~" (#"x~~" #"~~"))
       (#"(?<![cd])b" #"dbcb" #f)
       (#"(?<![cd])[ab]" #"dbaacb" (#"a"))
       (#"(?<!(c|d))[ab]" #"dbaacb" (#"a" #f))
       (#"(?<!cd)[ab]" #"cdaccb" (#"b"))
       #"^(?:a?b?)*$"
       #"^(?:a?b?)*$"
       (#"(?=(a+?))(\\1ab)" #"aaab" (#"aab" #"a" #"aab"))
       (#"(\\w+:)+" #"one:" (#"one:" #"one:"))
       (#"$(?<=^(a))" #"a" (#"" #"a"))
       (#"(?=(a+?))(\\1ab)" #"aaab" (#"aab" #"a" #"aab"))
       (#"^(?=(a+?))\\1ab" #"aaab" #f)
       (#"^(?=(a+?))\\1ab" #"aaab" #f)
       (#"([\\w:]+::)?(\\w+)$" #"abcd" (#"abcd" #f #"abcd"))
       (#"([\\w:]+::)?(\\w+)$" #"xy:z:::abcd" (#"xy:z:::abcd" #"xy:z:::" #"abcd"))
       (#"^[^bcd]*(c+)" #"aexycd" (#"aexyc" #"c"))
       (#"(a*)b+" #"caab" (#"aab" #"aa"))
       (#"([\\w:]+::)?(\\w+)$" #"abcd" (#"abcd" #f #"abcd"))
       (#"([\\w:]+::)?(\\w+)$" #"xy:z:::abcd" (#"xy:z:::abcd" #"xy:z:::" #"abcd"))
       (#"([\\w:]+::)?(\\w+)$" #"abcd:" #f)
       (#"([\\w:]+::)?(\\w+)$" #"abcd:" #f)
       (#"^[^bcd]*(c+)" #"aexycd" (#"aexyc" #"c"))
       (#"(?>a+)b" #"aaab" (#"aaab"))
       (#"([[:]+)" #"a:[b]:" (#":[" #":["))
       (#"([[=]+)" #"a=[b]=" (#"=[" #"=["))
       (#"([[.]+)" #"a.[b]." (#".[" #".["))
       (#"((?>a+)b)" #"aaab" (#"aaab" #"aaab"))
       (#"(?>(a+))b" #"aaab" (#"aaab" #"aaa"))
       (#"((?>[^()]+)|\\([^()]*\\))+" #"((abc(ade)ufh()()x" (#"abc(ade)ufh()()x" #"x"))
       (#"(?>.*)(?<=(abcd|wxyz))" #"alphabetabcd" (#"alphabetabcd" #"abcd"))
       (#"(?>.*)(?<=(abcd|wxyz))" #"endingwxyz" (#"endingwxyz" #"wxyz"))
       (#"(?>.*)(?<=(abcd|wxyz))" #"a rather long string that doesn't end with one of them" #f)
       (#"word (?>(?:(?!otherword)[a-zA-Z0-9]+ ){0,30})otherword" #"word cat dog elephant mussel cow horse canary baboon snake shark otherword" (#"word cat dog elephant mussel cow horse canary baboon snake shark otherword"))
       (#"word (?>(?:(?!otherword)[a-zA-Z0-9]+ ){0,30})otherword" #"word cat dog elephant mussel cow horse canary baboon snake shark" #f)
       (#"word (?>[a-zA-Z0-9]+ ){0,30}otherword" #"word cat dog elephant mussel cow horse canary baboon snake shark the quick brown fox and the lazy dog and several other words getting close to thirty by now I hope" #f)
       (#"(?<=\\d{3}(?!999))foo" #"999foo" (#"foo"))
       (#"(?<=\\d{3}(?!999))foo" #"123999foo " (#"foo"))
       (#"(?<=\\d{3}(?!999))foo" #"123abcfoo" #f)
       (#"(?<=(?!...999)\\d{3})foo" #"999foo" (#"foo"))
       (#"(?<=(?!...999)\\d{3})foo" #"123999foo " (#"foo"))
       (#"(?<=(?!...999)\\d{3})foo" #"123abcfoo" #f)
       (#"(?<=\\d{3}(?!999)...)foo" #"123abcfoo" (#"foo"))
       (#"(?<=\\d{3}(?!999)...)foo" #"123456foo " (#"foo"))
       (#"(?<=\\d{3}(?!999)...)foo" #"123999foo  " #f)
       (#"(?<=\\d{3}...)(?<!999)foo" #"123abcfoo   " (#"foo"))
       (#"(?<=\\d{3}...)(?<!999)foo" #"123456foo " (#"foo"))
       (#"(?<=\\d{3}...)(?<!999)foo" #"123999foo  " #f)
       (#"((Z)+|A)*" #"ZABCDEFG" (#"ZA" #"A" #"Z"))
       (#"(Z()|A)*" #"ZABCDEFG" (#"ZA" #"A" #""))
       (#"(Z(())|A)*" #"ZABCDEFG" (#"ZA" #"A" #"" #""))
       (#"((?>Z)+|A)*" #"ZABCDEFG" (#"ZA" #"A"))
       #"((?>)+|A)*"
       #"^[a-\\d]"
       #"^[\\d-a]"
       (#"(?<=abc).*(?=def)" #"abcdef" (#""))
       (#"(?<=abc).*(?=def)" #"abcxdef" (#"x"))
       (#"(?<=abc).*(?=def)" #"abcxdefxdef" (#"xdefx"))
       (#"(?<=abc).*?(?=def)" #"abcdef" (#""))
       (#"(?<=abc).*?(?=def)" #"abcxdef" (#"x"))
       (#"(?<=abc).*?(?=def)" #"abcxdefxdef" (#"x"))
       (#"(?<=abc).+(?=def)" #"abcdef" #f)
       (#"(?<=abc).+(?=def)" #"abcxdef" (#"x"))
       (#"(?<=abc).+(?=def)" #"abcxdefxdef" (#"xdefx"))
       (#"(?<=abc).+?(?=def)" #"abcdef" #f)
       (#"(?<=abc).+?(?=def)" #"abcxdef" (#"x"))
       (#"(?<=abc).+?(?=def)" #"abcxdefxdef" (#"x"))
       (#"(?<=\\b)(.*)" #"-abcdef" (#"abcdef" #"abcdef"))
       (#"(?<=\\b)(.*)" #"abcdef" (#"abcdef" #"abcdef"))
       (#"(?<=\\B)(.*)" #"-abcdef" (#"-abcdef" #"-abcdef"))
       (#"(?<=\\B)(.*)" #"abcdef" (#"bcdef" #"bcdef"))
       (#"^'[ab]'" #"'a'" (#"'a'"))
       (#"^'[ab]'" #"'b'" (#"'b'"))
       (#"^'[ab]'" #"x'a'" #f)
       (#"^'[ab]'" #"'a'x" (#"'a'"))
       (#"^'[ab]'" #"'ab'" #f)
       (#"^'[ab]'$" #"'a'" (#"'a'"))
       (#"^'[ab]'$" #"'b'" (#"'b'"))
       (#"^'[ab]'$" #"x'a'" #f)
       (#"^'[ab]'$" #"'a'x" #f)
       (#"^'[ab]'$" #"'ab'" #f)
       (#"'[ab]'$" #"'a'" (#"'a'"))
       (#"'[ab]'$" #"'b'" (#"'b'"))
       (#"'[ab]'$" #"x'a'" (#"'a'"))
       (#"'[ab]'$" #"'a'x" #f)
       (#"'[ab]'$" #"'ab'" #f)
       (#"'[ab]'" #"'a'" (#"'a'"))
       (#"'[ab]'" #"'b'" (#"'b'"))
       (#"'[ab]'" #"x'a'" (#"'a'"))
       (#"'[ab]'" #"'a'x" (#"'a'"))
       (#"'[ab]'" #"'ab'" #f)
       (#"ab(?=.*q)cd" #"abcdxklqj" (#"abcd"))
       (#"a(?!.*$)b" #"ab" #f)
       (#".{2}[a-z]" #"Axi" (#"Axi"))
       (#"^12.34" #"12\n34" (#"12\n34"))
       (#"(?m:^12.34)" #"12\n34" #f)
       (#"(?s:^12.34)" #"12\n34" (#"12\n34"))
       (#"(?m:^12.34)" #"12x34" (#"12x34"))
       (#"(?s:^12.34)" #"12x34" (#"12x34"))
       (#"^a" #"a\nb\nc" (#"a"))
       (#"^a$" #"a\nb\nc" #f)
       (#"(?m:^a)" #"a\nb\nc" (#"a"))
       (#"(?m:^a$)" #"a\nb\nc" (#"a"))
       (#"^b" #"a\nb\nc" #f)
       (#"b$" #"a\nb\nc" #f)
       (#"^b$" #"a\nb\nc" #f)
       (#"(?m:^b)" #"a\nb\nc" (#"b"))
       (#"(?m:b$)" #"a\nb\nc" (#"b"))
       (#"(?m:^b$)" #"a\nb\nc" (#"b"))
       (#"(?m:a[^a]^b)" #"a\nb\nc" (#"a\nb"))
       (#"(?m:a[^a]^b$)" #"a\nb\nc" (#"a\nb"))
       (#"(?m:a$[^a]^b$)" #"a\nb\nc" (#"a\nb"))
       (#"(?m:a[^a]^b[^a]^c)" #"a\nb\nc" (#"a\nb\nc"))
       (#"(?m:^a$[^a]^b$[^a]^c$)" #"a\nb\nc" (#"a\nb\nc"))
       #"(?())"
       #"(?(a))"
       #"(a)(?(\\1))"
       #"(?(1))"
       #"(?(1)a|b|c)"
       #"(?(?=x)a|b|c)"
       #"(?(?=x)a"
       #"(?(?=x)a|b"
       #"(?(?=x)a|b|"
       (#"(a)?(?(1)12|b12)" #"a12" (#"a12" #"a"))
       (#"(a)?(?(1)12|b12)" #"b12" (#"b12" #f))
       (#"(a)?(?(1)12|b12)" #"b13" #f)
       (#"(a)?(?(1)|b12)" #"a12" (#"a" #"a"))
       (#"(a)?(?(1)12)" #"a12" (#"a12" #"a"))
       (#"(a)?(?(1)12)" #"b12" (#"" #f))
       (#"(?(?=a)a12|b12)" #"a12" (#"a12"))
       (#"(?(?=a)a12|b12)" #"b12" (#"b12"))
       (#"(?(?=a)a12|b12)" #"c12" #f)
       (#"(?(?=a)a12|b12)" #"b13" #f)
       (#"(?(?!a).12|a13)" #"a13" (#"a13"))
       (#"(?(?!a).12|a13)" #"b12" (#"b12"))
       (#"(?(?!a).12|a13)" #"c12" (#"c12"))
       (#"(?(?!a).12|a13)" #"c13" #f)
       (#"(?(?<=a)12|13)" #"a12" (#"12"))
       (#"(?(?<=a)12|13)" #"b13" (#"13"))
       (#"(?(?<=a)12|13)" #"a13" #f)
       (#"(?(?<=a)12|13)" #"b12" #f)
       (#"(?(?<!a)12|13)" #"b12" (#"12"))
       (#"(?(?<!a)12|13)" #"a13" (#"13"))
       (#"(?(?<!a)12|13)" #"b13" #f)
       (#"(?(?<!a)12|13)" #"a12" #f)
       (#"^(E)?(?(1)aa|a)*$" #"Ea" #f)
       (#"^(E)?(?(1)aa|a)*$" #"Eaa" (#"Eaa" #"E"))
       (#"^(E)?(?(1)aa|a)*$" #"Eaaa" #f)
       (#"^(E)?(?(1)aa|a)*$" #"Eaaaa" (#"Eaaaa" #"E"))
       (#"^(E)?(?(1)aa|a)*$" #"aaa" (#"aaa" #f))
       (#"^(E)?(?(1)aa|a)*$" #"aaaa" (#"aaaa" #f))))


(let ()
  (define out (open-output-bytes))
  (define infinite-voids
    (make-input-port
     'voids
     (lambda (s) (lambda args 'void))
     (lambda (skip s evt) (lambda args 'void))
     void))
  (err/rt-test (regexp-match #rx"." infinite-voids)
               exn:fail:contract?
               #rx"non-character in an unsupported context"))

;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;  Test unicode-property patterns

(test '((0 . 2)) regexp-match-positions #px#".\\p{L}" #"0X")

(let ([just-once? #t]
      [kcrl (make-known-char-range-list)]
      [ht (make-hasheq)]
      [bformat (lambda (s v)
		 (string->bytes/latin-1 (format s v)))])
  (for-each (lambda (str)
	      (hash-set! ht 
                         (string->symbol (string-downcase str))
                         (vector
                          (byte-pregexp (bformat "\\p{~a}" str))
                          (pregexp (format "\\p{~a}" str))
                          (byte-pregexp (bformat "\\p{~a}*" str))
                          (pregexp (format "\\p{~a}*" str))
                          (byte-pregexp (bformat "\\P{~a}" str))
                          (pregexp (format "\\P{~a}" str))
                          (byte-pregexp (bformat "\\P{~a}*" str))
                          (pregexp (format "\\P{~a}*" str))

                          ;; Unicode categories can be negated with \P
                          ;; or by prefixing the category name with ^.
                          ;; These should be equivalent to the first
                          ;; 8 regexps, respectively.
                          (byte-pregexp (bformat "\\P{^~a}" str))
                          (pregexp (format "\\P{^~a}" str))
                          (byte-pregexp (bformat "\\P{^~a}*" str))
                          (pregexp (format "\\P{^~a}*" str))
                          (byte-pregexp (bformat "\\P{~a}" str))
                          (pregexp (format "\\p{^~a}" str))
                          (byte-pregexp (bformat "\\P{~a}*" str))
                          (pregexp (format "\\p{^~a}*" str)))))
	    '("Cn" "Cc" "Cf" "Cs" "Co" "Ll" "Lu" "Lt" "Lm" "Lo" "Nd" "Nl" "No"
	      "Ps" "Pe" "Pi" "Pf" "Pc" "Pd" "Po" "Mn" "Mc" "Me" "Sc" "Sk" "Sm" "So" "Zl" "Zp" "Zs"))
  (define equiv-offsets (list 0 8))
  (for-each
   (lambda (off)
     (define (ref v i)
       (vector-ref v (+ i off)))
     (hash-for-each ht
                    (lambda (k v)
                      (let ([bad1 #"\377\377"]
                            [bad2 (regexp-replace #rx#".$"
                                                  (string->bytes/utf-8 "\U10FFF1")
                                                  #"\377")]
                            [bad3 (regexp-replace #rx#".$"
                                                  (string->bytes/utf-8 "\u1234")
                                                  #"")])
                        (test #f regexp-match (ref v 0) bad1)
                        (test #f regexp-match (ref v 0) bad2)
                        (test #f regexp-match (ref v 0) bad3)
                        (test #f regexp-match (ref v 1) bad1)
                        (test #f regexp-match (ref v 1) bad2)
                        (test #f regexp-match (ref v 1) bad3)
                        (test #f regexp-match (ref v 4) bad1)
                        (test #f regexp-match (ref v 4) bad2)
                        (test #f regexp-match (ref v 4) bad3)
                        (test #f regexp-match (ref v 5) bad1)
                        (test #f regexp-match (ref v 5) bad2)
                        (test #f regexp-match (ref v 5) bad3)
                        (let ([other (ormap (lambda (e)
                                              (and (not (eq? k (char-general-category
                                                                (integer->char (car e)))))
                                                   (integer->char (car e))))
                                            kcrl)])
                          (let* ([s (string other)]
                                 [bs (string->bytes/utf-8 s)]
                                 [s* (string-append s s s)]
                                 [bs* (bytes-append bs bs bs)])
                            (test #f regexp-match (ref v 0) bs)
                            (test #f regexp-match (ref v 1) s)
                            (test '(#"") regexp-match (ref v 2) bs)
                            (test '("") regexp-match (ref v 3) s)
                            (test (list bs) regexp-match (ref v 4) bs)
                            (test (list s) regexp-match (ref v 5) s)
                            (test (list bs*) regexp-match (ref v 6) bs*)
                            (test (list s*) regexp-match (ref v 7) s*))))))
     (let ([try (lambda (n)
                  (let* ([cat (char-general-category (integer->char n))]
                         [v (hash-ref ht cat #f)])
                    (when v
                          (when just-once?
                                (hash-remove! ht cat))
                          (let* ([s (string (integer->char n))]
                                 [bs (string->bytes/utf-8 s)]
                                 [bs* (string->bytes/utf-8 (string-append s s s s s))]
                                 [regexp-match* (lambda (p s)
                                                  (let ([v (regexp-match p (bytes->string/utf-8 s))])
                                                    (and v
                                                         (map string->bytes/utf-8 v))))])
                            (test (list bs) regexp-match (ref v 0) bs)
                            (test (list bs) regexp-match* (ref v 1) bs)
                            (test (list bs*) regexp-match (ref v 2) bs*)
                            (test (list bs*) regexp-match* (ref v 3) bs*)))))])
       (for-each (lambda (e)
                   (let ([start (car e)]
                         [end (cadr e)]
                         [uniform? (caddr e)])
                     (let loop ([n start])
                       (try n)
                       (unless (= n end)
                               (loop (if uniform? end (+ n 1)))))))
                 kcrl)))
   equiv-offsets))


(test '(#" ") regexp-match #px#"\t|\\p{Zs}" " ")
(test '(" ") regexp-match #px"\t|\\p{Zs}" " ")
(test '(#"\t") regexp-match #px#"\t|\\p{Zs}" "\t")
(test '("\t") regexp-match #px"\t|\\p{Zs}" "\t")
(test #f regexp-match #px#"\t|\\p{Zs}" "a")
(test #f regexp-match #px"\t|\\p{Zs}" "a")

;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;; Check that [\s] doesn't match \s, etc.
(let ([test-both
       (lambda (r bstr arg)
         (test (and r (list r))regexp-match (byte-pregexp bstr) arg)
         (test (and r (list (bytes->string/latin-1 r)) )
               regexp-match 
               (pregexp (bytes->string/latin-1 bstr))
               (bytes->string/latin-1 arg)))])
  (test-both #f #"[\\s]" #"a")
  (test-both #f #"[\\s]" #"s")
  (test-both #" " #"[\\s]" #" ")
  (test-both #"a" #"[^\\s]" #"a")
  (test-both #"s" #"[^\\s]" #"s")
  (test-both #f #"[^\\s]" #" "))

;; Check that rx doesn't parse as px:
(test '(#"aa" #"a") regexp-match #px#"(a)\\1" #"aa")
(test '(#"a1" #"a") regexp-match #rx#"(a)\\1" #"a1")
(test '(#"a") regexp-match #px#"\\w" #"aw")
(test '(#"w") regexp-match #rx#"\\w" #"aw")
(test '(#"0") regexp-match #px#"\\d" #"0w")
(test '(#"d") regexp-match #rx#"\\d" #"0d")
(test '(#"0") regexp-match #px#"[\\d]" #"0w")
(test '(#"d") regexp-match #rx#"[\\d]" #"0d")
(test '(#"\\") regexp-match #rx#"[\\d]" #"0\\")

;; Check $:
(test '(#"$") regexp-match #px#"\\$" #"a$b")
(test '(#"$") regexp-match #rx#"\\$" #"a$b")
(test '(#"a$") regexp-match #px#"a\\$" #"a$b")
(test '(#"a$") regexp-match #rx#"a\\$" #"a$b")

;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;; Check prefixes and suffixes that disallow matches at ^ at start or $ at end:
(let ([try
       (lambda (regexp-match input output [output2 output])
         (let ([try-succeed
                (lambda (output i s e)
                  (test (output (list "a")) regexp-match #rx"^a" (i) s e #f #"")
                  (test (output (list "a")) regexp-match #rx"(?m:^a)" (i) s e #f #"\n")
                  (test (output (list "a")) regexp-match #rx"(?m:^a)" (i) s e #f #"x\n"))])
           (try-succeed output (lambda () (input "a")) 0 #f)
           (try-succeed output2 (lambda () (input "xay")) 1 2))
         (let ([try-fail
                (lambda (i s e)
                  (test #f regexp-match #rx"^a" (i) s e #f #"\n")
                  (test #f regexp-match #rx"^a" (i) s e #f #"x\n")
                  (let ([try-always-fail
                         (lambda (m)
                           (test #f regexp-match (m #rx"^a") (i) s e #f #"x")
                           (test #f regexp-match (m #rx"^a") (i) s e #f #"\nx"))])
                    (try-always-fail values)
                    (try-always-fail (lambda (rx) (regexp (format "(?m:~a)" (object-name rx)))))))])
           (try-fail (lambda () (input "a")) 0 #f)
           (try-fail (lambda () (input "xay")) 1 2)))])
  (try regexp-match values values)
  (try regexp-match? values (lambda (a) (and a #t)))
  (try regexp-match string->bytes/utf-8 (lambda (l) (map string->bytes/utf-8 l)))
  (try regexp-match open-input-string (lambda (l) (map string->bytes/utf-8 l)))
  (try regexp-match-positions values 
       (lambda (s) (and s '((0 . 1))))
       (lambda (s) (and s '((1 . 2))))))

;; regexp-replace* disallows start matching after the first match:
(test "baa" regexp-replace* #rx"^a" "aaa" "b")

;; regexp-replace* disallows start matching after the first match:
(test "bbb" regexp-replace* #rx"(?m:^a\n)" "a\na\na\n" "b")
(test "bba\n" regexp-replace* #rx"(?m:^a[z\n])" "a\naza\n" "b")

(test-values `(("abc") #"c")
             (lambda () (regexp-match/end #rx".*" "abc")))
(test-values `(((0 . 3)) #"c")
             (lambda () (regexp-match-positions/end #rx".*" "abc")))
(test-values `(((0 . 3)) #"c")
             (lambda () (regexp-match-peek-positions/end #rx".*" (open-input-string "abc"))))
(test-values `(((0 . 3)) #"c")
             (lambda () (regexp-match-peek-positions-immediate/end #rx".*" (open-input-string "abc"))))

;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Test failure handlers

(define (requote s) (regexp-replace* #rx"'" s "`"))

(test "`+` follows nothing in pattern" regexp "+" requote)
(test "`+` follows nothing in pattern" pregexp "+" requote)
(test "`+` follows nothing in pattern" byte-regexp #"+" requote)
(test "`+` follows nothing in pattern" byte-pregexp #"+" requote)
(test 3 regexp "+" (λ (s) (+ 1 2)))
(test 3 pregexp "+" (λ (s) (+ 1 2)))
(test 3 byte-regexp #"+" (λ (s) (+ 1 2)))
(test 3 byte-pregexp #"+" (λ (s) (+ 1 2)))

(test-values '(1 2 3) (lambda () (byte-pregexp #"+" (λ (s) (values 1 2 3)))))

(err/rt-test (regexp "+" #f) (lambda (exn) (regexp-match? "`[+]. follows nothing in pattern" (exn-message exn))))

;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Make sure that negated patterns as literal strings are not recorded
;; as "must include this literal string" requirements

(test '("aaa") regexp-match #rx"a*(?!b)" "aaaxy")
(test '("aaa") regexp-match #rx"a*(?<!b)" "aaaxy")

;; Make sure "must match" strings are preserved for non-negated
;; lookahead and lookbehind; the following examples take
;; quadratic time without the "must match" optimization,
;; and return return away with #f for with the optimization
(test #f 'optimized (regexp-match #px"a*(?=bc)" (make-bytes 100024 (char->integer #\a))))
(test #f 'optimized (regexp-match #px"a*(?<=bc)" (make-bytes 100024 (char->integer #\a))))

;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Ensure that regexp-replace can handle sub-matches that are #f
;; (https://github.com/racket/racket/issues/3032)
;;
(test "" regexp-replace "(x)?" "" (lambda a ""))
(test "" regexp-replace "(x)?" "" "\\1")

(test "x" regexp-replace "x(y)?(z)?" "x" "&\\1\\2")
(test "xyy" regexp-replace "x(y)?(z)?" "xy" "&\\1\\2")

(test "xyy[z]" regexp-replace "x(y)?(z)?" "xy" (lambda (x y z)
                                                 (string-append x
                                                                (or y "[y]")
                                                                (or z "[z]"))))

;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Don't get stuck waiting for an unneeded byte

(let ()
  (define-values (i o) (make-pipe))
  (write-string "1\n" o)
  (define rx (regexp "^(?:(.*?)(?:\r\n|\n))"))
  (test '(#"1\n" #"1") regexp-match rx i))
(let ()
  (define-values (i o) (make-pipe))
  (write-string "abc" o)
  (define rx (regexp "^(ab)*"))
  (test '(#"ab" #"ab") regexp-match rx i))
(let ()
  (define-values (i o) (make-pipe))
  (write-string "123" o)
  (define rx (pregexp "^(12)\\1|123"))
  (test '(#"123" #f) regexp-match rx i))

;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;; Check that `regexp-match/end` produces the right suffix
;; when a string to convert is large enough that its
;; conversion is internally streamed
(for ([N (in-list '(100 1000 10000 100000))])
  (test-values (list '(#"") #"!")
               (lambda ()
                 (regexp-match/end (byte-pregexp #"(?=b)")
                                   (bytes-append (make-bytes N (char->integer #\a)) #"!b"))))
  (test-values (list '(#"") #"!")
               (lambda ()
                 (regexp-match/end (byte-pregexp #"(?=b)")
                                   (string-append (make-string N #\a) "!b"))))
  (test-values (list '("") #"!")
               (lambda ()
                 (regexp-match/end (pregexp "(?=b)")
                                   (string-append (make-string N #\a) "!b"))))

  (test-values (list (list (cons (add1 N) (add1 N))) #"!")
               (lambda ()
                 (regexp-match-positions/end (byte-pregexp #"(?=b)")
                                             (bytes-append (make-bytes N (char->integer #\a)) #"!b"))))

  (test-values (list (list (cons (add1 N) (add1 N))) #"!")
               (lambda ()
                 (regexp-match-positions/end (byte-pregexp #"(?=b)")
                                             (string-append (make-string N #\a) "!b"))))
  (test-values (list (list (cons (add1 N) (add1 N))) #"!")
               (lambda ()
                 (regexp-match-positions/end (pregexp "(?=b)")
                                             (string-append (make-string N #\a) "!b"))))

  (test-values (list '(#"") #"!")
               (lambda ()
                 (regexp-match/end (byte-pregexp #"(?=b)")
                                   (bytes-append (make-bytes N (char->integer #\a)) #"!b")
                                   0 #f #f #"prefix")))
  (test-values (list '(#"") #"!")
               (lambda ()
                 (regexp-match/end (byte-pregexp #"(?=b)")
                                   (string-append (make-string N #\a) "!b")
                                   0 #f #f #"prefix")))
  (test-values (list '("") #"!")
               (lambda ()
                 (regexp-match/end (pregexp "(?=b)")
                                   (string-append (make-string N #\a) "!b")
                                   0 #f #f #"prefix")))

  (test-values (list (list (cons (add1 N) (add1 N))) #"!")
               (lambda ()
                 (regexp-match-positions/end (byte-pregexp #"(?=b)")
                                             (bytes-append (make-bytes N (char->integer #\a)) #"!b")
                                             0 #f #f #"prefix")))
  (test-values (list (list (cons (add1 N) (add1 N))) #"!")
               (lambda ()
                 (regexp-match-positions/end (byte-pregexp #"(?=b)")
                                             (string-append (make-string N #\a) "!b")
                                             0 #f #f #"prefix")))
  (test-values (list (list (cons (add1 N) (add1 N))) #"!")
               (lambda ()
                 (regexp-match-positions/end (pregexp "(?=b)")
                                             (string-append (make-string N #\a) "!b")
                                             0 #f #f #"prefix")))

  (test-values (list (list (cons (add1 N) (add1 N)))
                     (bytes-append (make-bytes (sub1 N) (char->integer #\a)) #"!"))
               (lambda ()
                 (regexp-match-positions/end (byte-pregexp #"(?=b)")
                                             (bytes-append (make-bytes N (char->integer #\a)) #"!b")
                                             0 #f #f #"prefix" N)))
  (test-values (list (list (cons (add1 N) (add1 N)))
                     (bytes-append (make-bytes (sub1 N) (char->integer #\a)) #"!"))
               (lambda ()
                 (regexp-match-positions/end (byte-pregexp #"(?=b)")
                                             (string-append (make-string N #\a) "!b")
                                             0 #f #f #"prefix" N)))
  (test-values (list (list (cons (add1 N) (add1 N)))
                     (bytes-append (make-bytes (sub1 N) (char->integer #\a)) #"!"))
               (lambda ()
                 (regexp-match-positions/end (pregexp "(?=b)")
                                             (string-append (make-string N #\a) "!b")
                                             0 #f #f #"prefix" N))))

;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;; Match groups spans prefix:
(test '((1 . 1) (-1 . 1))
      regexp-match-positions (regexp "(?<=(..))") "aaa" 0 #f #f #"x")
(test '((2 . 2) (0 . 2))
      regexp-match-positions (regexp "(?<=(..))") "aaa" 1 #f #f #"x")
(test '((0 . 0) (-1 . 0))
      regexp-match-positions (regexp "(?<=(.))") "aaa" 0 #f #f #"x")
(test '((0 . 0) (-1 . 0))
      regexp-match-positions (byte-regexp #"(?<=(.))") #"aaa" 0 #f #f #"x")
(test '((0 . 0) (-1 . 0))
      regexp-match-peek-positions (byte-regexp #"(?<=(.))") (open-input-bytes #"aaa") 0 #f #f #"x")
(test '((2 . 2) (0 . 2))
      regexp-match-positions (byte-regexp #"(?<=(..))") #"aaa" 1 #f #f #"x")
(test '((0 . 0) (-1 . 0))
      regexp-match-positions (regexp "(?<=(.))") "aaa" 0 #f #f (string->bytes/utf-8 "\u3BB"))
(test '((0 . 1) (-1 . 0))
      regexp-match-positions (regexp "(?<=(.)).") "\u03BBaa" 0 #f #f (string->bytes/utf-8 "\u3BC"))
(test '((1 . 2) (-1 . 1))
      regexp-match-positions (regexp "(?<=(..)).") "\u03BBaa" 0 #f #f (string->bytes/utf-8 "\u3BC"))
(test '("" "\u3BB")
      regexp-match (regexp "(?<=(.))") "aaa" 0 #f #f (string->bytes/utf-8 "\u3BB"))
(test '("a" "\u3BB")
      regexp-match (regexp "(?<=(.)).") "aaa" 0 #f #f (string->bytes/utf-8 "\u3BB"))
(test '("a" "\u03BBa")
      regexp-match (regexp "(?<=(..)).") "aaa" 0 #f #f (string->bytes/utf-8 "\u3BB"))
(test '("\u3BB" "\u3BC")
      regexp-match (regexp "(?<=(.)).") "\u03BBaa" 0 #f #f (string->bytes/utf-8 "\u3BC"))
(test '(#"" #"x")
      regexp-match (byte-regexp #"(?<=(.))") #"aaa" 0 #f #f #"x")
(test '(#"ab" #"x")
      regexp-match (byte-regexp #"(?<=(.))..") (open-input-bytes #"abc") 0 #f #f #"x")
(test '(#"ab" #"x")
      regexp-match-peek (byte-regexp #"(?<=(.))..") (open-input-bytes #"abc") 0 #f #f #"x")

;; Replacement where match groups spans prefix:
(test #"[x]aaa"
      regexp-replace (byte-regexp #"(?<=(.))") #"aaa" #"[\\1]" #"x")
(test #"a[xa]aa"
      regexp-replace (byte-regexp #"(?<=(..))") #"aaa" #"[\\1]" #"x")
(test #"[x]aa"
      regexp-replace (byte-regexp #"(?<=(.)).") #"aaa" #"[\\1]" #"x")
(test "[x]aaa"
      regexp-replace (regexp "(?<=(.))") "aaa" "[\\1]" #"x")
(test "a[xa]aa"
      regexp-replace (regexp "(?<=(..))") "aaa" "[\\1]" #"x")
(test "[x]aa"
      regexp-replace (regexp "(?<=(.)).") "aaa" "[\\1]" #"x")
(test "[x]aa"
      regexp-replace (regexp "(?<=(.)).") "aaa" "[\\1]" #"\xFFx")
(test "a[a]c"
      regexp-replace (regexp "(?<=(.)).") "abc" "[\\1]" #"\xFF")
(test "[\u03BBx]aa"
      regexp-replace (regexp "(?<=(..)).") "aaa" "[\\1]"
      (bytes-append #"\xFF"
                    (string->bytes/utf-8 "\u03BBx")))
(test #"{bx}aa"
      regexp-replace (byte-regexp #"(?<=(..)).") #"aaa" (lambda (m m1) (bytes-append #"{" m1 #"}"))
      #"\xFFbx")
(test "{\u03BBx}aa"
      regexp-replace (regexp "(?<=(..)).") "aaa" (lambda (m m1) (string-append "{" m1 "}"))
      (bytes-append #"\xFF"
                    (string->bytes/utf-8 "\u03BBx")))
(test #"a{xa}c"
      regexp-replace (byte-regexp #"(?<=(..)).") #"abc" (lambda (m m1) (bytes-append #"{" m1 #"}"))
      #"x")
(test "a{\u03BBa}c"
      regexp-replace (regexp "(?<=(..)).") "abc" (lambda (m m1) (string-append "{" m1 "}"))
      (bytes-append #"\xFF"
                    (string->bytes/utf-8 "\u03BB")))
(test "\u03BC{\u03BB\u03BC}c"
      regexp-replace (regexp "(?<=(..)).") "\u03BCbc" (lambda (m m1) (string-append "{" m1 "}"))
      (bytes-append #"\xFF"
                    (string->bytes/utf-8 "\u03BB")))


(test #"[x]a[a]a[a]a[a]"
      regexp-replace* (byte-regexp #"(?<=(.))") #"aaa" #"[\\1]" 0 #f #"x")
(test #"a[xa]b[ab]c[bc]"
      regexp-replace* (byte-regexp #"(?<=(..))") #"abc" #"[\\1]" 0 #f #"x")
(test #"[x][a][b]"
      regexp-replace* (byte-regexp #"(?<=(.)).") #"abc" #"[\\1]" 0 #f #"x")
(test "[x]a[a]a[a]a[a]"
      regexp-replace* (regexp "(?<=(.))") "aaa" "[\\1]" 0 #f #"x")
(test "a[xa]b[ab]c[bc]"
      regexp-replace* (regexp "(?<=(..))") "abc" "[\\1]" 0 #f #"x")
(test "[x][a][b]"
      regexp-replace* (regexp "(?<=(.)).") "abc" "[\\1]" 0 #f #"x")
(test "[x][a][b]"
      regexp-replace* (regexp "(?<=(.)).") "abc" "[\\1]" 0 #f #"\xFFx")
(test "a[a][b]"
      regexp-replace* (regexp "(?<=(.)).") "abc" "[\\1]" 0 #f #"\xFF")
(test "[\u03BBx][xa][ab]"
      regexp-replace* (regexp "(?<=(..)).") "abc" "[\\1]" 0 #f
      (bytes-append #"\xFF"
                    (string->bytes/utf-8 "\u03BBx")))
(test #"{bx}{xa}{ay}"
      regexp-replace* (byte-regexp #"(?<=(..)).") #"ayz" (lambda (m m1) (bytes-append #"{" m1 #"}")) 0 #f
      #"\xFFbx")
(test "{\u03BBx}{xa}{ab}"
      regexp-replace* (regexp "(?<=(..)).") "abc" (lambda (m m1) (string-append "{" m1 "}")) 0 #f
      (bytes-append #"\xFF"
                    (string->bytes/utf-8 "\u03BBx")))
(test #"a{xa}{ab}"
      regexp-replace* (byte-regexp #"(?<=(..)).") #"abc" (lambda (m m1) (bytes-append #"{" m1 #"}")) 0 #f
      #"x")
(test "a{\u03BBa}{ab}"
      regexp-replace* (regexp "(?<=(..)).") "abc" (lambda (m m1) (string-append "{" m1 "}")) 0 #f
      (bytes-append #"\xFF"
                    (string->bytes/utf-8 "\u03BB")))
(test "\u03BC{\u03BB\u03BC}{\u03BCb}"
      regexp-replace* (regexp "(?<=(..)).") "\u03BCbc" (lambda (m m1) (string-append "{" m1 "}")) 0 #f
      (bytes-append #"\xFF"
                    (string->bytes/utf-8 "\u03BB")))

(test #"" regexp-replace* #"[a-z]" #"abc" #"")
(test "" regexp-replace* "[a-z]" "abc" "")

;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(test "aaa" regexp-replace* "(x)" "aaa"
      ;; no error, even though this is the wrong arity:
      (lambda (x) x))

(err/rt-test (regexp-replace* "(a)" "aaa" (lambda (x) x))
             exn:fail:contract:arity?)

;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(report-errs)
